14-consistency-check.tcl 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. source "../tests/includes/init-tests.tcl"
  2. source "../../../tests/support/cli.tcl"
  3. test "Create a 5 nodes cluster" {
  4. create_cluster 5 5
  5. }
  6. test "Cluster should start ok" {
  7. assert_cluster_state ok
  8. }
  9. test "Cluster is writable" {
  10. cluster_write_test 0
  11. }
  12. proc find_non_empty_master {} {
  13. set master_id_no {}
  14. foreach_redis_id id {
  15. if {[RI $id role] eq {master} && [R $id dbsize] > 0} {
  16. set master_id_no $id
  17. }
  18. }
  19. return $master_id_no
  20. }
  21. proc get_one_of_my_replica {id} {
  22. set replica_port [lindex [lindex [lindex [R $id role] 2] 0] 1]
  23. set replica_id_num [get_instance_id_by_port redis $replica_port]
  24. return $replica_id_num
  25. }
  26. proc cluster_write_keys_with_expire {id ttl} {
  27. set prefix [randstring 20 20 alpha]
  28. set port [get_instance_attrib redis $id port]
  29. set cluster [redis_cluster 127.0.0.1:$port]
  30. for {set j 100} {$j < 200} {incr j} {
  31. $cluster setex key_expire.$j $ttl $prefix.$j
  32. }
  33. $cluster close
  34. }
  35. # make sure that replica who restarts from persistence will load keys
  36. # that have already expired, critical for correct execution of commands
  37. # that arrive from the master
  38. proc test_slave_load_expired_keys {aof} {
  39. test "Slave expired keys is loaded when restarted: appendonly=$aof" {
  40. set master_id [find_non_empty_master]
  41. set replica_id [get_one_of_my_replica $master_id]
  42. set master_dbsize_0 [R $master_id dbsize]
  43. set replica_dbsize_0 [R $replica_id dbsize]
  44. assert_equal $master_dbsize_0 $replica_dbsize_0
  45. # config the replica persistency and rewrite the config file to survive restart
  46. # note that this needs to be done before populating the volatile keys since
  47. # that triggers and AOFRW, and we rather the AOF file to have 'SET PXAT' commands
  48. # rather than an RDB with volatile keys
  49. R $replica_id config set appendonly $aof
  50. R $replica_id config rewrite
  51. # fill with 100 keys with 3 second TTL
  52. set data_ttl 3
  53. cluster_write_keys_with_expire $master_id $data_ttl
  54. # wait for replica to be in sync with master
  55. wait_for_condition 500 10 {
  56. [R $replica_id dbsize] eq [R $master_id dbsize]
  57. } else {
  58. fail "replica didn't sync"
  59. }
  60. set replica_dbsize_1 [R $replica_id dbsize]
  61. assert {$replica_dbsize_1 > $replica_dbsize_0}
  62. # make replica create persistence file
  63. if {$aof == "yes"} {
  64. # we need to wait for the initial AOFRW to be done, otherwise
  65. # kill_instance (which now uses SIGTERM will fail ("Writing initial AOF, can't exit")
  66. wait_for_condition 100 10 {
  67. [RI $replica_id aof_rewrite_in_progress] eq 0
  68. } else {
  69. fail "keys didn't expire"
  70. }
  71. } else {
  72. R $replica_id save
  73. }
  74. # kill the replica (would stay down until re-started)
  75. kill_instance redis $replica_id
  76. # Make sure the master doesn't do active expire (sending DELs to the replica)
  77. R $master_id DEBUG SET-ACTIVE-EXPIRE 0
  78. # wait for all the keys to get logically expired
  79. after [expr $data_ttl*1000]
  80. # start the replica again (loading an RDB or AOF file)
  81. restart_instance redis $replica_id
  82. # make sure the keys are still there
  83. set replica_dbsize_3 [R $replica_id dbsize]
  84. assert {$replica_dbsize_3 > $replica_dbsize_0}
  85. # restore settings
  86. R $master_id DEBUG SET-ACTIVE-EXPIRE 1
  87. # wait for the master to expire all keys and replica to get the DELs
  88. wait_for_condition 500 10 {
  89. [R $replica_id dbsize] eq $master_dbsize_0
  90. } else {
  91. fail "keys didn't expire"
  92. }
  93. }
  94. }
  95. test_slave_load_expired_keys no
  96. test_slave_load_expired_keys yes