@nxtedition/rocksdb 5.2.21 → 5.2.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (909) hide show
  1. package/binding.cc +216 -252
  2. package/binding.gyp +78 -72
  3. package/deps/rocksdb/build_version.cc +70 -4
  4. package/deps/rocksdb/rocksdb/CMakeLists.txt +281 -149
  5. package/deps/rocksdb/rocksdb/Makefile +459 -469
  6. package/deps/rocksdb/rocksdb/README.md +4 -4
  7. package/deps/rocksdb/rocksdb/TARGETS +5244 -1500
  8. package/deps/rocksdb/rocksdb/cache/cache.cc +12 -3
  9. package/deps/rocksdb/rocksdb/cache/cache_bench.cc +7 -368
  10. package/deps/rocksdb/rocksdb/cache/cache_bench_tool.cc +924 -0
  11. package/deps/rocksdb/rocksdb/cache/cache_entry_roles.cc +128 -0
  12. package/deps/rocksdb/rocksdb/cache/cache_entry_roles.h +103 -0
  13. package/deps/rocksdb/rocksdb/cache/cache_entry_stats.h +183 -0
  14. package/deps/rocksdb/rocksdb/cache/cache_helpers.h +11 -0
  15. package/deps/rocksdb/rocksdb/cache/cache_key.cc +344 -0
  16. package/deps/rocksdb/rocksdb/cache/cache_key.h +132 -0
  17. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.cc +183 -0
  18. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager.h +288 -0
  19. package/deps/rocksdb/rocksdb/cache/cache_reservation_manager_test.cc +468 -0
  20. package/deps/rocksdb/rocksdb/cache/cache_test.cc +85 -8
  21. package/deps/rocksdb/rocksdb/cache/clock_cache.cc +121 -51
  22. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.cc +171 -0
  23. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache.h +86 -0
  24. package/deps/rocksdb/rocksdb/cache/compressed_secondary_cache_test.cc +607 -0
  25. package/deps/rocksdb/rocksdb/cache/lru_cache.cc +381 -154
  26. package/deps/rocksdb/rocksdb/cache/lru_cache.h +176 -33
  27. package/deps/rocksdb/rocksdb/cache/lru_cache_test.cc +1659 -3
  28. package/deps/rocksdb/rocksdb/cache/sharded_cache.cc +94 -23
  29. package/deps/rocksdb/rocksdb/cache/sharded_cache.h +49 -28
  30. package/deps/rocksdb/rocksdb/crash_test.mk +93 -0
  31. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.cc +54 -31
  32. package/deps/rocksdb/rocksdb/db/arena_wrapped_db_iter.h +10 -6
  33. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator.h +146 -0
  34. package/deps/rocksdb/rocksdb/db/blob/blob_counting_iterator_test.cc +326 -0
  35. package/deps/rocksdb/rocksdb/db/blob/blob_fetcher.cc +34 -0
  36. package/deps/rocksdb/rocksdb/db/blob/blob_fetcher.h +37 -0
  37. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition.cc +4 -2
  38. package/deps/rocksdb/rocksdb/db/blob/blob_file_addition_test.cc +8 -4
  39. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.cc +99 -40
  40. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder.h +20 -8
  41. package/deps/rocksdb/rocksdb/db/blob/blob_file_builder_test.cc +95 -83
  42. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.cc +13 -10
  43. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache.h +7 -4
  44. package/deps/rocksdb/rocksdb/db/blob/blob_file_cache_test.cc +37 -37
  45. package/deps/rocksdb/rocksdb/db/blob/blob_file_completion_callback.h +101 -0
  46. package/deps/rocksdb/rocksdb/db/blob/blob_file_meta.cc +8 -1
  47. package/deps/rocksdb/rocksdb/db/blob/blob_file_meta.h +6 -0
  48. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.cc +209 -44
  49. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader.h +37 -11
  50. package/deps/rocksdb/rocksdb/db/blob/blob_file_reader_test.cc +382 -179
  51. package/deps/rocksdb/rocksdb/db/blob/blob_garbage_meter.cc +100 -0
  52. package/deps/rocksdb/rocksdb/db/blob/blob_garbage_meter.h +102 -0
  53. package/deps/rocksdb/rocksdb/db/blob/blob_garbage_meter_test.cc +196 -0
  54. package/deps/rocksdb/rocksdb/db/blob/blob_index.h +3 -0
  55. package/deps/rocksdb/rocksdb/db/blob/blob_log_format.h +2 -1
  56. package/deps/rocksdb/rocksdb/db/blob/blob_log_sequential_reader.cc +7 -5
  57. package/deps/rocksdb/rocksdb/db/blob/blob_log_sequential_reader.h +10 -3
  58. package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.cc +12 -8
  59. package/deps/rocksdb/rocksdb/db/blob/blob_log_writer.h +5 -5
  60. package/deps/rocksdb/rocksdb/db/blob/db_blob_basic_test.cc +772 -9
  61. package/deps/rocksdb/rocksdb/db/blob/db_blob_compaction_test.cc +730 -0
  62. package/deps/rocksdb/rocksdb/db/blob/db_blob_corruption_test.cc +82 -0
  63. package/deps/rocksdb/rocksdb/db/blob/db_blob_index_test.cc +155 -17
  64. package/deps/rocksdb/rocksdb/db/blob/prefetch_buffer_collection.cc +21 -0
  65. package/deps/rocksdb/rocksdb/db/blob/prefetch_buffer_collection.h +38 -0
  66. package/deps/rocksdb/rocksdb/db/builder.cc +137 -89
  67. package/deps/rocksdb/rocksdb/db/builder.h +16 -37
  68. package/deps/rocksdb/rocksdb/db/c.cc +413 -208
  69. package/deps/rocksdb/rocksdb/db/c_test.c +227 -138
  70. package/deps/rocksdb/rocksdb/db/column_family.cc +118 -103
  71. package/deps/rocksdb/rocksdb/db/column_family.h +86 -44
  72. package/deps/rocksdb/rocksdb/db/column_family_test.cc +38 -24
  73. package/deps/rocksdb/rocksdb/db/compact_files_test.cc +81 -0
  74. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator.h +275 -0
  75. package/deps/rocksdb/rocksdb/db/compaction/clipping_iterator_test.cc +258 -0
  76. package/deps/rocksdb/rocksdb/db/compaction/compaction.cc +81 -28
  77. package/deps/rocksdb/rocksdb/db/compaction/compaction.h +43 -12
  78. package/deps/rocksdb/rocksdb/db/compaction/compaction_iteration_stats.h +12 -0
  79. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.cc +406 -215
  80. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator.h +147 -50
  81. package/deps/rocksdb/rocksdb/db/compaction/compaction_iterator_test.cc +167 -61
  82. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.cc +1321 -156
  83. package/deps/rocksdb/rocksdb/db/compaction/compaction_job.h +197 -28
  84. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_stats_test.cc +2 -3
  85. package/deps/rocksdb/rocksdb/db/compaction/compaction_job_test.cc +246 -43
  86. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.cc +65 -26
  87. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker.h +7 -7
  88. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.cc +122 -9
  89. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_fifo.h +8 -2
  90. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.cc +18 -6
  91. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_level.h +1 -1
  92. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_test.cc +536 -44
  93. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.cc +311 -30
  94. package/deps/rocksdb/rocksdb/db/compaction/compaction_picker_universal.h +1 -1
  95. package/deps/rocksdb/rocksdb/db/compaction/compaction_service_test.cc +849 -0
  96. package/deps/rocksdb/rocksdb/db/compaction/file_pri.h +92 -0
  97. package/deps/rocksdb/rocksdb/db/compaction/sst_partitioner.cc +46 -0
  98. package/deps/rocksdb/rocksdb/db/comparator_db_test.cc +1 -1
  99. package/deps/rocksdb/rocksdb/db/convenience.cc +6 -3
  100. package/deps/rocksdb/rocksdb/db/corruption_test.cc +383 -28
  101. package/deps/rocksdb/rocksdb/db/cuckoo_table_db_test.cc +7 -2
  102. package/deps/rocksdb/rocksdb/db/db_basic_test.cc +154 -45
  103. package/deps/rocksdb/rocksdb/db/db_block_cache_test.cc +1095 -33
  104. package/deps/rocksdb/rocksdb/db/db_bloom_filter_test.cc +1249 -203
  105. package/deps/rocksdb/rocksdb/db/db_compaction_filter_test.cc +135 -9
  106. package/deps/rocksdb/rocksdb/db/db_compaction_test.cc +1348 -166
  107. package/deps/rocksdb/rocksdb/db/db_dynamic_level_test.cc +3 -5
  108. package/deps/rocksdb/rocksdb/db/db_encryption_test.cc +1 -1
  109. package/deps/rocksdb/rocksdb/db/db_filesnapshot.cc +312 -45
  110. package/deps/rocksdb/rocksdb/db/db_flush_test.cc +1734 -48
  111. package/deps/rocksdb/rocksdb/db/{compacted_db_impl.cc → db_impl/compacted_db_impl.cc} +24 -7
  112. package/deps/rocksdb/rocksdb/db/{compacted_db_impl.h → db_impl/compacted_db_impl.h} +1 -1
  113. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.cc +644 -333
  114. package/deps/rocksdb/rocksdb/db/db_impl/db_impl.h +365 -92
  115. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_compaction_flush.cc +578 -210
  116. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_debug.cc +38 -16
  117. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_experimental.cc +17 -10
  118. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_files.cc +75 -74
  119. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_open.cc +450 -183
  120. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_readonly.cc +42 -9
  121. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.cc +232 -15
  122. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_secondary.h +42 -4
  123. package/deps/rocksdb/rocksdb/db/db_impl/db_impl_write.cc +297 -100
  124. package/deps/rocksdb/rocksdb/db/db_info_dumper.cc +16 -15
  125. package/deps/rocksdb/rocksdb/db/db_inplace_update_test.cc +31 -1
  126. package/deps/rocksdb/rocksdb/db/db_io_failure_test.cc +6 -5
  127. package/deps/rocksdb/rocksdb/db/db_iter.cc +218 -153
  128. package/deps/rocksdb/rocksdb/db/db_iter.h +14 -12
  129. package/deps/rocksdb/rocksdb/db/db_iter_stress_test.cc +1 -1
  130. package/deps/rocksdb/rocksdb/db/db_iter_test.cc +84 -160
  131. package/deps/rocksdb/rocksdb/db/db_iterator_test.cc +47 -6
  132. package/deps/rocksdb/rocksdb/db/db_kv_checksum_test.cc +204 -0
  133. package/deps/rocksdb/rocksdb/db/db_log_iter_test.cc +21 -13
  134. package/deps/rocksdb/rocksdb/db/db_logical_block_size_cache_test.cc +17 -10
  135. package/deps/rocksdb/rocksdb/db/db_memtable_test.cc +38 -24
  136. package/deps/rocksdb/rocksdb/db/db_merge_operand_test.cc +184 -19
  137. package/deps/rocksdb/rocksdb/db/db_merge_operator_test.cc +1 -1
  138. package/deps/rocksdb/rocksdb/db/db_options_test.cc +183 -3
  139. package/deps/rocksdb/rocksdb/db/db_properties_test.cc +409 -9
  140. package/deps/rocksdb/rocksdb/db/db_range_del_test.cc +92 -23
  141. package/deps/rocksdb/rocksdb/db/db_rate_limiter_test.cc +446 -0
  142. package/deps/rocksdb/rocksdb/db/{db_impl/db_secondary_test.cc → db_secondary_test.cc} +363 -35
  143. package/deps/rocksdb/rocksdb/db/db_sst_test.cc +520 -15
  144. package/deps/rocksdb/rocksdb/db/db_statistics_test.cc +50 -1
  145. package/deps/rocksdb/rocksdb/db/db_table_properties_test.cc +139 -4
  146. package/deps/rocksdb/rocksdb/db/db_tailing_iter_test.cc +1 -1
  147. package/deps/rocksdb/rocksdb/db/db_test.cc +669 -359
  148. package/deps/rocksdb/rocksdb/db/db_test2.cc +2110 -304
  149. package/deps/rocksdb/rocksdb/db/db_test_util.cc +76 -43
  150. package/deps/rocksdb/rocksdb/db/db_test_util.h +231 -103
  151. package/deps/rocksdb/rocksdb/db/db_universal_compaction_test.cc +19 -11
  152. package/deps/rocksdb/rocksdb/db/db_wal_test.cc +490 -71
  153. package/deps/rocksdb/rocksdb/db/db_with_timestamp_basic_test.cc +980 -349
  154. package/deps/rocksdb/rocksdb/db/db_with_timestamp_compaction_test.cc +11 -12
  155. package/deps/rocksdb/rocksdb/db/db_write_buffer_manager_test.cc +793 -0
  156. package/deps/rocksdb/rocksdb/db/db_write_test.cc +2 -1
  157. package/deps/rocksdb/rocksdb/db/dbformat.cc +4 -12
  158. package/deps/rocksdb/rocksdb/db/dbformat.h +28 -18
  159. package/deps/rocksdb/rocksdb/db/dbformat_test.cc +3 -0
  160. package/deps/rocksdb/rocksdb/db/deletefile_test.cc +50 -15
  161. package/deps/rocksdb/rocksdb/db/error_handler.cc +127 -41
  162. package/deps/rocksdb/rocksdb/db/error_handler.h +12 -5
  163. package/deps/rocksdb/rocksdb/db/error_handler_fs_test.cc +524 -255
  164. package/deps/rocksdb/rocksdb/db/event_helpers.cc +136 -11
  165. package/deps/rocksdb/rocksdb/db/event_helpers.h +27 -2
  166. package/deps/rocksdb/rocksdb/db/experimental.cc +100 -0
  167. package/deps/rocksdb/rocksdb/db/external_sst_file_basic_test.cc +307 -4
  168. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.cc +137 -60
  169. package/deps/rocksdb/rocksdb/db/external_sst_file_ingestion_job.h +12 -8
  170. package/deps/rocksdb/rocksdb/db/external_sst_file_test.cc +86 -55
  171. package/deps/rocksdb/rocksdb/db/fault_injection_test.cc +86 -5
  172. package/deps/rocksdb/rocksdb/db/filename_test.cc +63 -0
  173. package/deps/rocksdb/rocksdb/db/flush_job.cc +619 -64
  174. package/deps/rocksdb/rocksdb/db/flush_job.h +30 -7
  175. package/deps/rocksdb/rocksdb/db/flush_job_test.cc +33 -16
  176. package/deps/rocksdb/rocksdb/db/flush_scheduler.h +2 -1
  177. package/deps/rocksdb/rocksdb/db/forward_iterator.cc +18 -17
  178. package/deps/rocksdb/rocksdb/db/forward_iterator.h +5 -4
  179. package/deps/rocksdb/rocksdb/db/forward_iterator_bench.cc +0 -1
  180. package/deps/rocksdb/rocksdb/db/history_trimming_iterator.h +91 -0
  181. package/deps/rocksdb/rocksdb/db/import_column_family_job.cc +25 -14
  182. package/deps/rocksdb/rocksdb/db/import_column_family_job.h +6 -5
  183. package/deps/rocksdb/rocksdb/db/import_column_family_test.cc +1 -1
  184. package/deps/rocksdb/rocksdb/db/internal_stats.cc +471 -50
  185. package/deps/rocksdb/rocksdb/db/internal_stats.h +129 -25
  186. package/deps/rocksdb/rocksdb/db/job_context.h +22 -9
  187. package/deps/rocksdb/rocksdb/db/kv_checksum.h +394 -0
  188. package/deps/rocksdb/rocksdb/db/listener_test.cc +518 -41
  189. package/deps/rocksdb/rocksdb/db/log_format.h +4 -1
  190. package/deps/rocksdb/rocksdb/db/log_reader.cc +129 -6
  191. package/deps/rocksdb/rocksdb/db/log_reader.h +17 -1
  192. package/deps/rocksdb/rocksdb/db/log_test.cc +161 -11
  193. package/deps/rocksdb/rocksdb/db/log_writer.cc +92 -13
  194. package/deps/rocksdb/rocksdb/db/log_writer.h +18 -5
  195. package/deps/rocksdb/rocksdb/db/logs_with_prep_tracker.h +1 -1
  196. package/deps/rocksdb/rocksdb/db/lookup_key.h +0 -1
  197. package/deps/rocksdb/rocksdb/db/malloc_stats.cc +2 -2
  198. package/deps/rocksdb/rocksdb/db/manual_compaction_test.cc +21 -8
  199. package/deps/rocksdb/rocksdb/db/memtable.cc +144 -54
  200. package/deps/rocksdb/rocksdb/db/memtable.h +72 -15
  201. package/deps/rocksdb/rocksdb/db/memtable_list.cc +95 -47
  202. package/deps/rocksdb/rocksdb/db/memtable_list.h +33 -13
  203. package/deps/rocksdb/rocksdb/db/memtable_list_test.cc +61 -31
  204. package/deps/rocksdb/rocksdb/db/merge_context.h +20 -8
  205. package/deps/rocksdb/rocksdb/db/merge_helper.cc +54 -11
  206. package/deps/rocksdb/rocksdb/db/merge_helper.h +17 -6
  207. package/deps/rocksdb/rocksdb/db/merge_helper_test.cc +13 -7
  208. package/deps/rocksdb/rocksdb/db/merge_test.cc +40 -19
  209. package/deps/rocksdb/rocksdb/db/obsolete_files_test.cc +14 -25
  210. package/deps/rocksdb/rocksdb/db/output_validator.cc +3 -0
  211. package/deps/rocksdb/rocksdb/db/output_validator.h +5 -4
  212. package/deps/rocksdb/rocksdb/db/perf_context_test.cc +32 -28
  213. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler.cc +43 -29
  214. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler.h +9 -7
  215. package/deps/rocksdb/rocksdb/db/periodic_work_scheduler_test.cc +21 -16
  216. package/deps/rocksdb/rocksdb/db/pinned_iterators_manager.h +1 -1
  217. package/deps/rocksdb/rocksdb/db/plain_table_db_test.cc +29 -36
  218. package/deps/rocksdb/rocksdb/db/pre_release_callback.h +1 -2
  219. package/deps/rocksdb/rocksdb/db/prefix_test.cc +4 -4
  220. package/deps/rocksdb/rocksdb/db/range_del_aggregator.h +2 -2
  221. package/deps/rocksdb/rocksdb/db/range_del_aggregator_bench.cc +11 -11
  222. package/deps/rocksdb/rocksdb/db/range_del_aggregator_test.cc +3 -2
  223. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.cc +14 -8
  224. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter.h +17 -0
  225. package/deps/rocksdb/rocksdb/db/range_tombstone_fragmenter_test.cc +4 -2
  226. package/deps/rocksdb/rocksdb/db/read_callback.h +1 -0
  227. package/deps/rocksdb/rocksdb/db/repair.cc +87 -58
  228. package/deps/rocksdb/rocksdb/db/repair_test.cc +35 -5
  229. package/deps/rocksdb/rocksdb/db/snapshot_impl.h +2 -1
  230. package/deps/rocksdb/rocksdb/db/table_cache.cc +95 -69
  231. package/deps/rocksdb/rocksdb/db/table_cache.h +63 -53
  232. package/deps/rocksdb/rocksdb/db/table_properties_collector.cc +4 -4
  233. package/deps/rocksdb/rocksdb/db/table_properties_collector.h +78 -10
  234. package/deps/rocksdb/rocksdb/db/table_properties_collector_test.cc +28 -33
  235. package/deps/rocksdb/rocksdb/db/transaction_log_impl.cc +30 -51
  236. package/deps/rocksdb/rocksdb/db/transaction_log_impl.h +12 -8
  237. package/deps/rocksdb/rocksdb/db/version_builder.cc +564 -341
  238. package/deps/rocksdb/rocksdb/db/version_builder.h +8 -8
  239. package/deps/rocksdb/rocksdb/db/version_builder_test.cc +327 -155
  240. package/deps/rocksdb/rocksdb/db/version_edit.cc +89 -27
  241. package/deps/rocksdb/rocksdb/db/version_edit.h +42 -17
  242. package/deps/rocksdb/rocksdb/db/version_edit_handler.cc +324 -43
  243. package/deps/rocksdb/rocksdb/db/version_edit_handler.h +79 -22
  244. package/deps/rocksdb/rocksdb/db/version_edit_test.cc +165 -20
  245. package/deps/rocksdb/rocksdb/db/version_set.cc +935 -1034
  246. package/deps/rocksdb/rocksdb/db/version_set.h +183 -122
  247. package/deps/rocksdb/rocksdb/db/version_set_test.cc +556 -138
  248. package/deps/rocksdb/rocksdb/db/version_util.h +68 -0
  249. package/deps/rocksdb/rocksdb/db/wal_manager.cc +23 -21
  250. package/deps/rocksdb/rocksdb/db/wal_manager.h +5 -2
  251. package/deps/rocksdb/rocksdb/db/wal_manager_test.cc +30 -27
  252. package/deps/rocksdb/rocksdb/db/write_batch.cc +704 -209
  253. package/deps/rocksdb/rocksdb/db/write_batch_internal.h +135 -2
  254. package/deps/rocksdb/rocksdb/db/write_batch_test.cc +209 -5
  255. package/deps/rocksdb/rocksdb/db/write_callback_test.cc +2 -0
  256. package/deps/rocksdb/rocksdb/db/write_controller.cc +47 -54
  257. package/deps/rocksdb/rocksdb/db/write_controller.h +12 -9
  258. package/deps/rocksdb/rocksdb/db/write_controller_test.cc +215 -103
  259. package/deps/rocksdb/rocksdb/db/write_thread.cc +11 -0
  260. package/deps/rocksdb/rocksdb/db/write_thread.h +14 -8
  261. package/deps/rocksdb/rocksdb/db_stress_tool/CMakeLists.txt +7 -4
  262. package/deps/rocksdb/rocksdb/db_stress_tool/batched_ops_stress.cc +10 -3
  263. package/deps/rocksdb/rocksdb/db_stress_tool/cf_consistency_stress.cc +6 -0
  264. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress.cc +1 -1
  265. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.cc +19 -2
  266. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_common.h +78 -25
  267. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_compaction_filter.h +13 -2
  268. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_driver.cc +29 -12
  269. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_env_wrapper.h +5 -1
  270. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_gflags.cc +199 -32
  271. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.cc +188 -0
  272. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_listener.h +59 -10
  273. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_shared_state.h +77 -109
  274. package/deps/rocksdb/rocksdb/{third-party/folly/folly/synchronization/WaitOptions.cpp → db_stress_tool/db_stress_stat.cc} +9 -4
  275. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_stat.h +7 -6
  276. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_table_properties_collector.h +1 -0
  277. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.cc +699 -143
  278. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_test_base.h +20 -2
  279. package/deps/rocksdb/rocksdb/db_stress_tool/db_stress_tool.cc +49 -39
  280. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.cc +631 -0
  281. package/deps/rocksdb/rocksdb/db_stress_tool/expected_state.h +287 -0
  282. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.cc +1565 -0
  283. package/deps/rocksdb/rocksdb/db_stress_tool/multi_ops_txns_stress.h +374 -0
  284. package/deps/rocksdb/rocksdb/db_stress_tool/no_batched_ops_stress.cc +149 -18
  285. package/deps/rocksdb/rocksdb/env/composite_env.cc +464 -0
  286. package/deps/rocksdb/rocksdb/env/composite_env_wrapper.h +98 -646
  287. package/deps/rocksdb/rocksdb/env/emulated_clock.h +114 -0
  288. package/deps/rocksdb/rocksdb/env/env.cc +632 -42
  289. package/deps/rocksdb/rocksdb/env/env_basic_test.cc +84 -36
  290. package/deps/rocksdb/rocksdb/env/env_chroot.cc +88 -286
  291. package/deps/rocksdb/rocksdb/env/env_chroot.h +34 -1
  292. package/deps/rocksdb/rocksdb/env/env_encryption.cc +469 -277
  293. package/deps/rocksdb/rocksdb/env/env_encryption_ctr.h +9 -30
  294. package/deps/rocksdb/rocksdb/env/env_posix.cc +110 -119
  295. package/deps/rocksdb/rocksdb/env/env_test.cc +1128 -39
  296. package/deps/rocksdb/rocksdb/env/file_system.cc +147 -8
  297. package/deps/rocksdb/rocksdb/env/file_system_tracer.cc +207 -136
  298. package/deps/rocksdb/rocksdb/env/file_system_tracer.h +86 -54
  299. package/deps/rocksdb/rocksdb/env/fs_posix.cc +192 -64
  300. package/deps/rocksdb/rocksdb/env/fs_readonly.h +107 -0
  301. package/deps/rocksdb/rocksdb/env/fs_remap.cc +339 -0
  302. package/deps/rocksdb/rocksdb/env/fs_remap.h +139 -0
  303. package/deps/rocksdb/rocksdb/env/io_posix.cc +245 -41
  304. package/deps/rocksdb/rocksdb/env/io_posix.h +66 -1
  305. package/deps/rocksdb/rocksdb/env/mock_env.cc +147 -149
  306. package/deps/rocksdb/rocksdb/env/mock_env.h +113 -11
  307. package/deps/rocksdb/rocksdb/env/mock_env_test.cc +2 -4
  308. package/deps/rocksdb/rocksdb/env/unique_id_gen.cc +164 -0
  309. package/deps/rocksdb/rocksdb/env/unique_id_gen.h +71 -0
  310. package/deps/rocksdb/rocksdb/file/delete_scheduler.cc +9 -5
  311. package/deps/rocksdb/rocksdb/file/delete_scheduler.h +6 -4
  312. package/deps/rocksdb/rocksdb/file/delete_scheduler_test.cc +19 -12
  313. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.cc +459 -70
  314. package/deps/rocksdb/rocksdb/file/file_prefetch_buffer.h +205 -28
  315. package/deps/rocksdb/rocksdb/file/file_util.cc +39 -28
  316. package/deps/rocksdb/rocksdb/file/file_util.h +18 -27
  317. package/deps/rocksdb/rocksdb/file/filename.cc +59 -22
  318. package/deps/rocksdb/rocksdb/file/filename.h +13 -8
  319. package/deps/rocksdb/rocksdb/file/line_file_reader.cc +68 -0
  320. package/deps/rocksdb/rocksdb/file/line_file_reader.h +59 -0
  321. package/deps/rocksdb/rocksdb/file/prefetch_test.cc +1130 -6
  322. package/deps/rocksdb/rocksdb/file/random_access_file_reader.cc +220 -36
  323. package/deps/rocksdb/rocksdb/file/random_access_file_reader.h +69 -17
  324. package/deps/rocksdb/rocksdb/file/random_access_file_reader_test.cc +13 -12
  325. package/deps/rocksdb/rocksdb/file/read_write_util.cc +3 -38
  326. package/deps/rocksdb/rocksdb/file/read_write_util.h +0 -4
  327. package/deps/rocksdb/rocksdb/file/readahead_file_info.h +33 -0
  328. package/deps/rocksdb/rocksdb/file/sequence_file_reader.cc +57 -9
  329. package/deps/rocksdb/rocksdb/file/sequence_file_reader.h +58 -6
  330. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.cc +29 -54
  331. package/deps/rocksdb/rocksdb/file/sst_file_manager_impl.h +22 -29
  332. package/deps/rocksdb/rocksdb/file/writable_file_writer.cc +424 -50
  333. package/deps/rocksdb/rocksdb/file/writable_file_writer.h +66 -19
  334. package/deps/rocksdb/rocksdb/include/rocksdb/advanced_options.h +157 -66
  335. package/deps/rocksdb/rocksdb/include/rocksdb/c.h +224 -121
  336. package/deps/rocksdb/rocksdb/include/rocksdb/cache.h +333 -30
  337. package/deps/rocksdb/rocksdb/include/rocksdb/cache_bench_tool.h +14 -0
  338. package/deps/rocksdb/rocksdb/include/rocksdb/cleanable.h +1 -1
  339. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_filter.h +90 -50
  340. package/deps/rocksdb/rocksdb/include/rocksdb/compaction_job_stats.h +13 -5
  341. package/deps/rocksdb/rocksdb/include/rocksdb/comparator.h +20 -4
  342. package/deps/rocksdb/rocksdb/include/rocksdb/concurrent_task_limiter.h +8 -3
  343. package/deps/rocksdb/rocksdb/include/rocksdb/configurable.h +53 -12
  344. package/deps/rocksdb/rocksdb/include/rocksdb/convenience.h +31 -6
  345. package/deps/rocksdb/rocksdb/include/rocksdb/customizable.h +102 -7
  346. package/deps/rocksdb/rocksdb/include/rocksdb/data_structure.h +51 -0
  347. package/deps/rocksdb/rocksdb/include/rocksdb/db.h +370 -262
  348. package/deps/rocksdb/rocksdb/include/rocksdb/env.h +286 -87
  349. package/deps/rocksdb/rocksdb/include/rocksdb/env_encryption.h +124 -64
  350. package/deps/rocksdb/rocksdb/include/rocksdb/experimental.h +27 -0
  351. package/deps/rocksdb/rocksdb/include/rocksdb/file_checksum.h +21 -4
  352. package/deps/rocksdb/rocksdb/include/rocksdb/file_system.h +384 -41
  353. package/deps/rocksdb/rocksdb/include/rocksdb/filter_policy.h +111 -143
  354. package/deps/rocksdb/rocksdb/include/rocksdb/flush_block_policy.h +20 -6
  355. package/deps/rocksdb/rocksdb/include/rocksdb/functor_wrapper.h +56 -0
  356. package/deps/rocksdb/rocksdb/include/rocksdb/io_status.h +15 -33
  357. package/deps/rocksdb/rocksdb/include/rocksdb/iostats_context.h +37 -1
  358. package/deps/rocksdb/rocksdb/include/rocksdb/iterator.h +1 -3
  359. package/deps/rocksdb/rocksdb/include/rocksdb/listener.h +314 -26
  360. package/deps/rocksdb/rocksdb/include/rocksdb/memory_allocator.h +11 -7
  361. package/deps/rocksdb/rocksdb/include/rocksdb/memtablerep.h +50 -15
  362. package/deps/rocksdb/rocksdb/include/rocksdb/merge_operator.h +10 -3
  363. package/deps/rocksdb/rocksdb/include/rocksdb/metadata.h +186 -96
  364. package/deps/rocksdb/rocksdb/include/rocksdb/options.h +373 -103
  365. package/deps/rocksdb/rocksdb/include/rocksdb/perf_context.h +13 -3
  366. package/deps/rocksdb/rocksdb/include/rocksdb/persistent_cache.h +2 -2
  367. package/deps/rocksdb/rocksdb/include/rocksdb/rate_limiter.h +37 -7
  368. package/deps/rocksdb/rocksdb/include/rocksdb/rocksdb_namespace.h +6 -0
  369. package/deps/rocksdb/rocksdb/include/rocksdb/secondary_cache.h +87 -0
  370. package/deps/rocksdb/rocksdb/include/rocksdb/slice.h +5 -12
  371. package/deps/rocksdb/rocksdb/include/rocksdb/slice_transform.h +59 -30
  372. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_manager.h +11 -11
  373. package/deps/rocksdb/rocksdb/include/rocksdb/sst_file_writer.h +22 -0
  374. package/deps/rocksdb/rocksdb/include/rocksdb/sst_partitioner.h +17 -10
  375. package/deps/rocksdb/rocksdb/include/rocksdb/statistics.h +121 -41
  376. package/deps/rocksdb/rocksdb/include/rocksdb/stats_history.h +1 -0
  377. package/deps/rocksdb/rocksdb/include/rocksdb/status.h +114 -136
  378. package/deps/rocksdb/rocksdb/include/rocksdb/system_clock.h +116 -0
  379. package/deps/rocksdb/rocksdb/include/rocksdb/table.h +160 -18
  380. package/deps/rocksdb/rocksdb/include/rocksdb/table_properties.h +57 -15
  381. package/deps/rocksdb/rocksdb/include/rocksdb/thread_status.h +3 -1
  382. package/deps/rocksdb/rocksdb/include/rocksdb/trace_reader_writer.h +10 -6
  383. package/deps/rocksdb/rocksdb/include/rocksdb/trace_record.h +247 -0
  384. package/deps/rocksdb/rocksdb/include/rocksdb/trace_record_result.h +187 -0
  385. package/deps/rocksdb/rocksdb/include/rocksdb/transaction_log.h +1 -1
  386. package/deps/rocksdb/rocksdb/include/rocksdb/types.h +14 -24
  387. package/deps/rocksdb/rocksdb/include/rocksdb/unique_id.h +46 -0
  388. package/deps/rocksdb/rocksdb/include/rocksdb/universal_compaction.h +14 -4
  389. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/agg_merge.h +138 -0
  390. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backup_engine.h +631 -0
  391. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/cache_dump_load.h +142 -0
  392. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/checkpoint.h +12 -9
  393. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/customizable_util.h +368 -0
  394. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd.h +24 -0
  395. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/ldb_cmd_execute_result.h +4 -0
  396. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/object_registry.h +418 -63
  397. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_type.h +143 -73
  398. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/options_util.h +2 -2
  399. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/replayer.h +87 -0
  400. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/sim_cache.h +2 -2
  401. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/stackable_db.h +43 -5
  402. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/table_properties_collectors.h +18 -23
  403. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction.h +26 -0
  404. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db.h +32 -6
  405. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/transaction_db_mutex.h +1 -2
  406. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/write_batch_with_index.h +20 -1
  407. package/deps/rocksdb/rocksdb/include/rocksdb/version.h +30 -3
  408. package/deps/rocksdb/rocksdb/include/rocksdb/wal_filter.h +11 -2
  409. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch.h +89 -11
  410. package/deps/rocksdb/rocksdb/include/rocksdb/write_batch_base.h +11 -0
  411. package/deps/rocksdb/rocksdb/include/rocksdb/write_buffer_manager.h +108 -38
  412. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.cc +40 -23
  413. package/deps/rocksdb/rocksdb/logging/auto_roll_logger.h +12 -5
  414. package/deps/rocksdb/rocksdb/logging/auto_roll_logger_test.cc +100 -49
  415. package/deps/rocksdb/rocksdb/logging/env_logger.h +7 -5
  416. package/deps/rocksdb/rocksdb/logging/env_logger_test.cc +0 -1
  417. package/deps/rocksdb/rocksdb/logging/posix_logger.h +3 -9
  418. package/deps/rocksdb/rocksdb/memory/arena.cc +3 -1
  419. package/deps/rocksdb/rocksdb/memory/arena.h +1 -1
  420. package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.cc +171 -106
  421. package/deps/rocksdb/rocksdb/memory/jemalloc_nodump_allocator.h +31 -15
  422. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator.cc +15 -4
  423. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator.h +24 -8
  424. package/deps/rocksdb/rocksdb/memory/memory_allocator.cc +91 -0
  425. package/deps/rocksdb/rocksdb/memory/memory_allocator_test.cc +239 -0
  426. package/deps/rocksdb/rocksdb/memory/memory_usage.h +14 -1
  427. package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.cc +72 -9
  428. package/deps/rocksdb/rocksdb/memtable/hash_skiplist_rep.cc +52 -6
  429. package/deps/rocksdb/rocksdb/memtable/inlineskiplist.h +53 -0
  430. package/deps/rocksdb/rocksdb/memtable/inlineskiplist_test.cc +5 -5
  431. package/deps/rocksdb/rocksdb/memtable/memtablerep_bench.cc +17 -5
  432. package/deps/rocksdb/rocksdb/memtable/skiplist_test.cc +1 -1
  433. package/deps/rocksdb/rocksdb/memtable/skiplistrep.cc +87 -0
  434. package/deps/rocksdb/rocksdb/memtable/vectorrep.cc +20 -10
  435. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager.cc +148 -94
  436. package/deps/rocksdb/rocksdb/memtable/write_buffer_manager_test.cc +160 -62
  437. package/deps/rocksdb/rocksdb/microbench/CMakeLists.txt +17 -0
  438. package/deps/rocksdb/rocksdb/microbench/README.md +60 -0
  439. package/deps/rocksdb/rocksdb/microbench/db_basic_bench.cc +1360 -0
  440. package/deps/rocksdb/rocksdb/microbench/ribbon_bench.cc +153 -0
  441. package/deps/rocksdb/rocksdb/monitoring/histogram.cc +8 -15
  442. package/deps/rocksdb/rocksdb/monitoring/histogram.h +0 -1
  443. package/deps/rocksdb/rocksdb/monitoring/histogram_test.cc +18 -16
  444. package/deps/rocksdb/rocksdb/monitoring/histogram_windowing.cc +9 -7
  445. package/deps/rocksdb/rocksdb/monitoring/histogram_windowing.h +5 -3
  446. package/deps/rocksdb/rocksdb/monitoring/instrumented_mutex.cc +7 -5
  447. package/deps/rocksdb/rocksdb/monitoring/instrumented_mutex.h +37 -12
  448. package/deps/rocksdb/rocksdb/monitoring/iostats_context.cc +26 -6
  449. package/deps/rocksdb/rocksdb/monitoring/iostats_context_imp.h +6 -10
  450. package/deps/rocksdb/rocksdb/monitoring/perf_context.cc +14 -13
  451. package/deps/rocksdb/rocksdb/monitoring/perf_context_imp.h +19 -20
  452. package/deps/rocksdb/rocksdb/monitoring/perf_step_timer.h +18 -18
  453. package/deps/rocksdb/rocksdb/monitoring/statistics.cc +84 -2
  454. package/deps/rocksdb/rocksdb/monitoring/statistics.h +6 -0
  455. package/deps/rocksdb/rocksdb/monitoring/statistics_test.cc +47 -2
  456. package/deps/rocksdb/rocksdb/monitoring/stats_history_test.cc +67 -54
  457. package/deps/rocksdb/rocksdb/monitoring/thread_status_updater.cc +4 -1
  458. package/deps/rocksdb/rocksdb/monitoring/thread_status_util.cc +2 -1
  459. package/deps/rocksdb/rocksdb/monitoring/thread_status_util_debug.cc +2 -2
  460. package/deps/rocksdb/rocksdb/options/cf_options.cc +280 -212
  461. package/deps/rocksdb/rocksdb/options/cf_options.h +51 -57
  462. package/deps/rocksdb/rocksdb/options/configurable.cc +242 -138
  463. package/deps/rocksdb/rocksdb/options/configurable_helper.h +4 -68
  464. package/deps/rocksdb/rocksdb/options/configurable_test.cc +144 -21
  465. package/deps/rocksdb/rocksdb/options/configurable_test.h +2 -3
  466. package/deps/rocksdb/rocksdb/options/customizable.cc +67 -7
  467. package/deps/rocksdb/rocksdb/options/customizable_test.cc +1773 -151
  468. package/deps/rocksdb/rocksdb/options/db_options.cc +275 -47
  469. package/deps/rocksdb/rocksdb/options/db_options.h +36 -7
  470. package/deps/rocksdb/rocksdb/options/options.cc +49 -17
  471. package/deps/rocksdb/rocksdb/options/options_helper.cc +369 -352
  472. package/deps/rocksdb/rocksdb/options/options_helper.h +23 -23
  473. package/deps/rocksdb/rocksdb/options/options_parser.cc +18 -13
  474. package/deps/rocksdb/rocksdb/options/options_settable_test.cc +67 -54
  475. package/deps/rocksdb/rocksdb/options/options_test.cc +1162 -187
  476. package/deps/rocksdb/rocksdb/plugin/README.md +43 -0
  477. package/deps/rocksdb/rocksdb/port/jemalloc_helper.h +1 -1
  478. package/deps/rocksdb/rocksdb/port/lang.h +52 -0
  479. package/deps/rocksdb/rocksdb/port/port_example.h +1 -1
  480. package/deps/rocksdb/rocksdb/port/port_posix.cc +31 -2
  481. package/deps/rocksdb/rocksdb/port/port_posix.h +20 -2
  482. package/deps/rocksdb/rocksdb/port/stack_trace.cc +20 -4
  483. package/deps/rocksdb/rocksdb/port/sys_time.h +2 -2
  484. package/deps/rocksdb/rocksdb/port/win/env_default.cc +7 -7
  485. package/deps/rocksdb/rocksdb/port/win/env_win.cc +44 -74
  486. package/deps/rocksdb/rocksdb/port/win/env_win.h +25 -23
  487. package/deps/rocksdb/rocksdb/port/win/io_win.cc +32 -34
  488. package/deps/rocksdb/rocksdb/port/win/io_win.h +12 -6
  489. package/deps/rocksdb/rocksdb/port/win/port_win.cc +55 -35
  490. package/deps/rocksdb/rocksdb/port/win/port_win.h +22 -5
  491. package/deps/rocksdb/rocksdb/port/win/win_logger.cc +3 -3
  492. package/deps/rocksdb/rocksdb/port/win/win_logger.h +3 -5
  493. package/deps/rocksdb/rocksdb/port/win/win_thread.cc +7 -1
  494. package/deps/rocksdb/rocksdb/port/win/win_thread.h +12 -17
  495. package/deps/rocksdb/rocksdb/python.mk +9 -0
  496. package/deps/rocksdb/rocksdb/src.mk +82 -34
  497. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.cc +3 -4
  498. package/deps/rocksdb/rocksdb/table/adaptive/adaptive_table_factory.h +1 -1
  499. package/deps/rocksdb/rocksdb/table/block_based/block.cc +158 -80
  500. package/deps/rocksdb/rocksdb/table/block_based/block.h +64 -36
  501. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.cc +23 -14
  502. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block.h +13 -5
  503. package/deps/rocksdb/rocksdb/table/block_based/block_based_filter_block_test.cc +3 -218
  504. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.cc +603 -328
  505. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_builder.h +28 -22
  506. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.cc +220 -82
  507. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_factory.h +8 -2
  508. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.cc +3 -4
  509. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_iterator.h +28 -4
  510. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.cc +598 -492
  511. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader.h +151 -96
  512. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_impl.h +31 -58
  513. package/deps/rocksdb/rocksdb/table/block_based/block_based_table_reader_test.cc +330 -92
  514. package/deps/rocksdb/rocksdb/table/block_based/block_builder.cc +50 -19
  515. package/deps/rocksdb/rocksdb/table/block_based/block_builder.h +23 -0
  516. package/deps/rocksdb/rocksdb/table/block_based/block_like_traits.h +226 -0
  517. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.cc +56 -22
  518. package/deps/rocksdb/rocksdb/table/block_based/block_prefetcher.h +42 -4
  519. package/deps/rocksdb/rocksdb/table/block_based/block_test.cc +5 -2
  520. package/deps/rocksdb/rocksdb/table/block_based/block_type.h +2 -0
  521. package/deps/rocksdb/rocksdb/table/block_based/cachable_entry.h +34 -20
  522. package/deps/rocksdb/rocksdb/table/block_based/data_block_hash_index_test.cc +9 -10
  523. package/deps/rocksdb/rocksdb/table/block_based/filter_block.h +26 -3
  524. package/deps/rocksdb/rocksdb/table/block_based/filter_block_reader_common.cc +2 -1
  525. package/deps/rocksdb/rocksdb/table/block_based/filter_policy.cc +844 -202
  526. package/deps/rocksdb/rocksdb/table/block_based/filter_policy_internal.h +281 -81
  527. package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.cc +62 -2
  528. package/deps/rocksdb/rocksdb/table/block_based/flush_block_policy.h +2 -3
  529. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.cc +28 -7
  530. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block.h +22 -6
  531. package/deps/rocksdb/rocksdb/table/block_based/full_filter_block_test.cc +28 -26
  532. package/deps/rocksdb/rocksdb/table/block_based/hash_index_reader.cc +1 -1
  533. package/deps/rocksdb/rocksdb/table/block_based/index_builder.cc +1 -2
  534. package/deps/rocksdb/rocksdb/table/block_based/index_reader_common.cc +2 -1
  535. package/deps/rocksdb/rocksdb/table/block_based/mock_block_based_table.h +11 -4
  536. package/deps/rocksdb/rocksdb/table/block_based/parsed_full_filter_block.cc +2 -1
  537. package/deps/rocksdb/rocksdb/table/block_based/parsed_full_filter_block.h +2 -0
  538. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.cc +68 -26
  539. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block.h +44 -9
  540. package/deps/rocksdb/rocksdb/table/block_based/partitioned_filter_block_test.cc +12 -10
  541. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.cc +3 -4
  542. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_iterator.h +23 -4
  543. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.cc +44 -19
  544. package/deps/rocksdb/rocksdb/table/block_based/partitioned_index_reader.h +5 -1
  545. package/deps/rocksdb/rocksdb/table/block_based/reader_common.cc +16 -28
  546. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.cc +7 -4
  547. package/deps/rocksdb/rocksdb/table/block_based/uncompression_dict_reader.h +2 -2
  548. package/deps/rocksdb/rocksdb/table/block_fetcher.cc +77 -57
  549. package/deps/rocksdb/rocksdb/table/block_fetcher.h +23 -12
  550. package/deps/rocksdb/rocksdb/table/block_fetcher_test.cc +43 -56
  551. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.cc +8 -8
  552. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder.h +2 -1
  553. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_builder_test.cc +52 -70
  554. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.cc +5 -8
  555. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_factory.h +1 -1
  556. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.cc +17 -11
  557. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader.h +2 -3
  558. package/deps/rocksdb/rocksdb/table/cuckoo/cuckoo_table_reader_test.cc +42 -51
  559. package/deps/rocksdb/rocksdb/table/format.cc +258 -104
  560. package/deps/rocksdb/rocksdb/table/format.h +120 -109
  561. package/deps/rocksdb/rocksdb/table/get_context.cc +97 -65
  562. package/deps/rocksdb/rocksdb/table/get_context.h +19 -12
  563. package/deps/rocksdb/rocksdb/table/internal_iterator.h +14 -0
  564. package/deps/rocksdb/rocksdb/table/iterator_wrapper.h +8 -0
  565. package/deps/rocksdb/rocksdb/table/merger_test.cc +3 -2
  566. package/deps/rocksdb/rocksdb/table/merging_iterator.cc +11 -21
  567. package/deps/rocksdb/rocksdb/table/merging_iterator.h +3 -3
  568. package/deps/rocksdb/rocksdb/table/meta_blocks.cc +176 -171
  569. package/deps/rocksdb/rocksdb/table/meta_blocks.h +47 -33
  570. package/deps/rocksdb/rocksdb/table/mock_table.cc +7 -9
  571. package/deps/rocksdb/rocksdb/table/mock_table.h +3 -2
  572. package/deps/rocksdb/rocksdb/table/multiget_context.h +15 -8
  573. package/deps/rocksdb/rocksdb/table/persistent_cache_helper.cc +22 -29
  574. package/deps/rocksdb/rocksdb/table/persistent_cache_options.h +6 -3
  575. package/deps/rocksdb/rocksdb/table/plain/plain_table_bloom.h +5 -8
  576. package/deps/rocksdb/rocksdb/table/plain/plain_table_builder.cc +29 -26
  577. package/deps/rocksdb/rocksdb/table/plain/plain_table_builder.h +12 -16
  578. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.cc +145 -69
  579. package/deps/rocksdb/rocksdb/table/plain/plain_table_factory.h +1 -1
  580. package/deps/rocksdb/rocksdb/table/plain/plain_table_index.cc +7 -6
  581. package/deps/rocksdb/rocksdb/table/plain/plain_table_index.h +3 -4
  582. package/deps/rocksdb/rocksdb/table/plain/plain_table_key_coding.cc +3 -1
  583. package/deps/rocksdb/rocksdb/table/plain/plain_table_key_coding.h +1 -1
  584. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.cc +13 -18
  585. package/deps/rocksdb/rocksdb/table/plain/plain_table_reader.h +4 -9
  586. package/deps/rocksdb/rocksdb/table/sst_file_dumper.cc +55 -37
  587. package/deps/rocksdb/rocksdb/table/sst_file_dumper.h +10 -5
  588. package/deps/rocksdb/rocksdb/table/sst_file_reader.cc +11 -8
  589. package/deps/rocksdb/rocksdb/table/sst_file_reader_test.cc +222 -16
  590. package/deps/rocksdb/rocksdb/table/sst_file_writer.cc +106 -58
  591. package/deps/rocksdb/rocksdb/table/sst_file_writer_collectors.h +6 -5
  592. package/deps/rocksdb/rocksdb/table/table_builder.h +68 -44
  593. package/deps/rocksdb/rocksdb/table/table_factory.cc +37 -10
  594. package/deps/rocksdb/rocksdb/table/table_properties.cc +109 -54
  595. package/deps/rocksdb/rocksdb/table/table_properties_internal.h +4 -20
  596. package/deps/rocksdb/rocksdb/table/table_reader_bench.cc +33 -32
  597. package/deps/rocksdb/rocksdb/table/table_reader_caller.h +2 -0
  598. package/deps/rocksdb/rocksdb/table/table_test.cc +989 -326
  599. package/deps/rocksdb/rocksdb/table/two_level_iterator.cc +4 -0
  600. package/deps/rocksdb/rocksdb/table/unique_id.cc +166 -0
  601. package/deps/rocksdb/rocksdb/table/unique_id_impl.h +59 -0
  602. package/deps/rocksdb/rocksdb/test_util/mock_time_env.cc +1 -1
  603. package/deps/rocksdb/rocksdb/test_util/mock_time_env.h +13 -10
  604. package/deps/rocksdb/rocksdb/test_util/sync_point.cc +1 -2
  605. package/deps/rocksdb/rocksdb/test_util/sync_point.h +35 -16
  606. package/deps/rocksdb/rocksdb/test_util/sync_point_impl.cc +32 -10
  607. package/deps/rocksdb/rocksdb/test_util/sync_point_impl.h +31 -4
  608. package/deps/rocksdb/rocksdb/test_util/testharness.cc +53 -1
  609. package/deps/rocksdb/rocksdb/test_util/testharness.h +67 -3
  610. package/deps/rocksdb/rocksdb/test_util/testutil.cc +236 -66
  611. package/deps/rocksdb/rocksdb/test_util/testutil.h +63 -100
  612. package/deps/rocksdb/rocksdb/test_util/transaction_test_util.cc +12 -1
  613. package/deps/rocksdb/rocksdb/tools/blob_dump.cc +2 -2
  614. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.cc +6 -3
  615. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer.h +1 -0
  616. package/deps/rocksdb/rocksdb/tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc +9 -3
  617. package/deps/rocksdb/rocksdb/tools/db_bench.cc +1 -1
  618. package/deps/rocksdb/rocksdb/tools/db_bench_tool.cc +1420 -611
  619. package/deps/rocksdb/rocksdb/tools/db_bench_tool_test.cc +11 -8
  620. package/deps/rocksdb/rocksdb/tools/db_repl_stress.cc +11 -1
  621. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_test.cc +4 -2
  622. package/deps/rocksdb/rocksdb/tools/io_tracer_parser_tool.cc +46 -22
  623. package/deps/rocksdb/rocksdb/tools/ldb_cmd.cc +655 -179
  624. package/deps/rocksdb/rocksdb/tools/ldb_cmd_impl.h +58 -6
  625. package/deps/rocksdb/rocksdb/tools/ldb_cmd_test.cc +472 -29
  626. package/deps/rocksdb/rocksdb/tools/ldb_tool.cc +23 -2
  627. package/deps/rocksdb/rocksdb/tools/reduce_levels_test.cc +2 -2
  628. package/deps/rocksdb/rocksdb/tools/simulated_hybrid_file_system.cc +246 -0
  629. package/deps/rocksdb/rocksdb/tools/simulated_hybrid_file_system.h +126 -0
  630. package/deps/rocksdb/rocksdb/tools/sst_dump_test.cc +83 -29
  631. package/deps/rocksdb/rocksdb/tools/sst_dump_tool.cc +38 -17
  632. package/deps/rocksdb/rocksdb/tools/trace_analyzer_test.cc +191 -55
  633. package/deps/rocksdb/rocksdb/tools/trace_analyzer_tool.cc +219 -296
  634. package/deps/rocksdb/rocksdb/tools/trace_analyzer_tool.h +87 -53
  635. package/deps/rocksdb/rocksdb/tools/write_stress.cc +8 -7
  636. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.cc +6 -5
  637. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer.h +5 -4
  638. package/deps/rocksdb/rocksdb/trace_replay/block_cache_tracer_test.cc +14 -9
  639. package/deps/rocksdb/rocksdb/trace_replay/io_tracer.cc +134 -60
  640. package/deps/rocksdb/rocksdb/trace_replay/io_tracer.h +49 -38
  641. package/deps/rocksdb/rocksdb/trace_replay/io_tracer_test.cc +152 -15
  642. package/deps/rocksdb/rocksdb/trace_replay/trace_record.cc +206 -0
  643. package/deps/rocksdb/rocksdb/trace_replay/trace_record_handler.cc +190 -0
  644. package/deps/rocksdb/rocksdb/trace_replay/trace_record_handler.h +46 -0
  645. package/deps/rocksdb/rocksdb/trace_replay/trace_record_result.cc +146 -0
  646. package/deps/rocksdb/rocksdb/trace_replay/trace_replay.cc +475 -344
  647. package/deps/rocksdb/rocksdb/trace_replay/trace_replay.h +83 -95
  648. package/deps/rocksdb/rocksdb/util/autovector.h +38 -18
  649. package/deps/rocksdb/rocksdb/util/autovector_test.cc +1 -1
  650. package/deps/rocksdb/rocksdb/util/bloom_impl.h +4 -0
  651. package/deps/rocksdb/rocksdb/util/bloom_test.cc +276 -94
  652. package/deps/rocksdb/rocksdb/util/build_version.cc.in +81 -4
  653. package/deps/rocksdb/rocksdb/util/cast_util.h +22 -0
  654. package/deps/rocksdb/rocksdb/util/channel.h +2 -0
  655. package/deps/rocksdb/rocksdb/util/coding.h +1 -33
  656. package/deps/rocksdb/rocksdb/util/compaction_job_stats_impl.cc +8 -0
  657. package/deps/rocksdb/rocksdb/util/comparator.cc +163 -3
  658. package/deps/rocksdb/rocksdb/util/compression.cc +122 -0
  659. package/deps/rocksdb/rocksdb/util/compression.h +212 -7
  660. package/deps/rocksdb/rocksdb/util/compression_context_cache.cc +1 -3
  661. package/deps/rocksdb/rocksdb/util/crc32c.cc +165 -2
  662. package/deps/rocksdb/rocksdb/util/crc32c.h +6 -0
  663. package/deps/rocksdb/rocksdb/util/crc32c_arm64.cc +14 -0
  664. package/deps/rocksdb/rocksdb/util/crc32c_ppc.h +3 -0
  665. package/deps/rocksdb/rocksdb/util/crc32c_test.cc +47 -0
  666. package/deps/rocksdb/rocksdb/util/defer.h +30 -1
  667. package/deps/rocksdb/rocksdb/util/defer_test.cc +11 -0
  668. package/deps/rocksdb/rocksdb/util/duplicate_detector.h +3 -1
  669. package/deps/rocksdb/rocksdb/util/dynamic_bloom.h +3 -3
  670. package/deps/rocksdb/rocksdb/util/dynamic_bloom_test.cc +5 -4
  671. package/deps/rocksdb/rocksdb/util/fastrange.h +2 -0
  672. package/deps/rocksdb/rocksdb/util/file_checksum_helper.cc +36 -0
  673. package/deps/rocksdb/rocksdb/util/file_checksum_helper.h +3 -1
  674. package/deps/rocksdb/rocksdb/util/file_reader_writer_test.cc +512 -52
  675. package/deps/rocksdb/rocksdb/util/filter_bench.cc +65 -10
  676. package/deps/rocksdb/rocksdb/util/gflags_compat.h +6 -1
  677. package/deps/rocksdb/rocksdb/util/hash.cc +121 -3
  678. package/deps/rocksdb/rocksdb/util/hash.h +31 -1
  679. package/deps/rocksdb/rocksdb/util/hash128.h +26 -0
  680. package/deps/rocksdb/rocksdb/util/hash_containers.h +51 -0
  681. package/deps/rocksdb/rocksdb/util/hash_test.cc +194 -2
  682. package/deps/rocksdb/rocksdb/util/heap.h +6 -1
  683. package/deps/rocksdb/rocksdb/util/kv_map.h +1 -1
  684. package/deps/rocksdb/rocksdb/util/log_write_bench.cc +8 -6
  685. package/deps/rocksdb/rocksdb/util/math.h +74 -7
  686. package/deps/rocksdb/rocksdb/util/math128.h +13 -1
  687. package/deps/rocksdb/rocksdb/util/murmurhash.h +3 -3
  688. package/deps/rocksdb/rocksdb/util/random.cc +9 -0
  689. package/deps/rocksdb/rocksdb/util/random.h +6 -0
  690. package/deps/rocksdb/rocksdb/util/rate_limiter.cc +298 -144
  691. package/deps/rocksdb/rocksdb/util/rate_limiter.h +68 -19
  692. package/deps/rocksdb/rocksdb/util/rate_limiter_test.cc +335 -23
  693. package/deps/rocksdb/rocksdb/util/repeatable_thread.h +10 -12
  694. package/deps/rocksdb/rocksdb/util/repeatable_thread_test.cc +18 -15
  695. package/deps/rocksdb/rocksdb/util/ribbon_alg.h +98 -74
  696. package/deps/rocksdb/rocksdb/util/ribbon_config.cc +506 -0
  697. package/deps/rocksdb/rocksdb/util/ribbon_config.h +182 -0
  698. package/deps/rocksdb/rocksdb/util/ribbon_impl.h +154 -79
  699. package/deps/rocksdb/rocksdb/util/ribbon_test.cc +742 -365
  700. package/deps/rocksdb/rocksdb/util/set_comparator.h +2 -0
  701. package/deps/rocksdb/rocksdb/util/slice.cc +198 -35
  702. package/deps/rocksdb/rocksdb/util/slice_test.cc +30 -1
  703. package/deps/rocksdb/rocksdb/util/status.cc +32 -29
  704. package/deps/rocksdb/rocksdb/util/stop_watch.h +18 -18
  705. package/deps/rocksdb/rocksdb/util/string_util.cc +85 -6
  706. package/deps/rocksdb/rocksdb/util/string_util.h +47 -2
  707. package/deps/rocksdb/rocksdb/util/thread_guard.h +41 -0
  708. package/deps/rocksdb/rocksdb/util/thread_local.h +2 -2
  709. package/deps/rocksdb/rocksdb/util/thread_local_test.cc +22 -24
  710. package/deps/rocksdb/rocksdb/util/threadpool_imp.cc +7 -6
  711. package/deps/rocksdb/rocksdb/util/timer.h +55 -46
  712. package/deps/rocksdb/rocksdb/util/timer_test.cc +50 -48
  713. package/deps/rocksdb/rocksdb/util/user_comparator_wrapper.h +4 -0
  714. package/deps/rocksdb/rocksdb/util/vector_iterator.h +31 -15
  715. package/deps/rocksdb/rocksdb/util/work_queue.h +2 -0
  716. package/deps/rocksdb/rocksdb/util/xxhash.cc +35 -1144
  717. package/deps/rocksdb/rocksdb/util/xxhash.h +5117 -373
  718. package/deps/rocksdb/rocksdb/util/xxph3.h +1762 -0
  719. package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge.cc +238 -0
  720. package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge.h +49 -0
  721. package/deps/rocksdb/rocksdb/utilities/agg_merge/agg_merge_test.cc +134 -0
  722. package/deps/rocksdb/rocksdb/utilities/agg_merge/test_agg_merge.cc +104 -0
  723. package/deps/rocksdb/rocksdb/utilities/agg_merge/test_agg_merge.h +47 -0
  724. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine.cc +3164 -0
  725. package/deps/rocksdb/rocksdb/utilities/backup/backup_engine_impl.h +29 -0
  726. package/deps/rocksdb/rocksdb/utilities/{backupable/backupable_db_test.cc → backup/backup_engine_test.cc} +1679 -485
  727. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.cc +6 -4
  728. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_compaction_filter.h +14 -9
  729. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.cc +2 -0
  730. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db.h +1 -0
  731. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_gc_stats.h +4 -0
  732. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.cc +37 -27
  733. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl.h +8 -4
  734. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_impl_filesnapshot.cc +1 -1
  735. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_iterator.h +13 -10
  736. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_listener.h +5 -0
  737. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_db_test.cc +44 -25
  738. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_dump_tool.cc +3 -4
  739. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.cc +27 -19
  740. package/deps/rocksdb/rocksdb/utilities/blob_db/blob_file.h +4 -2
  741. package/deps/rocksdb/rocksdb/utilities/cache_dump_load.cc +69 -0
  742. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.cc +489 -0
  743. package/deps/rocksdb/rocksdb/utilities/cache_dump_load_impl.h +366 -0
  744. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_compaction_filter.cc +67 -4
  745. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_compaction_filter.h +21 -6
  746. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_functional_test.cc +107 -7
  747. package/deps/rocksdb/rocksdb/utilities/cassandra/cassandra_options.h +43 -0
  748. package/deps/rocksdb/rocksdb/utilities/cassandra/format.h +1 -1
  749. package/deps/rocksdb/rocksdb/utilities/cassandra/merge_operator.cc +24 -8
  750. package/deps/rocksdb/rocksdb/utilities/cassandra/merge_operator.h +7 -7
  751. package/deps/rocksdb/rocksdb/utilities/cassandra/serialize.h +5 -0
  752. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.cc +99 -218
  753. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_impl.h +8 -24
  754. package/deps/rocksdb/rocksdb/utilities/checkpoint/checkpoint_test.cc +114 -1
  755. package/deps/rocksdb/rocksdb/utilities/compaction_filters/layered_compaction_filter_base.h +6 -2
  756. package/deps/rocksdb/rocksdb/utilities/compaction_filters/remove_emptyvalue_compactionfilter.cc +0 -4
  757. package/deps/rocksdb/rocksdb/utilities/compaction_filters/remove_emptyvalue_compactionfilter.h +7 -6
  758. package/deps/rocksdb/rocksdb/utilities/compaction_filters.cc +56 -0
  759. package/deps/rocksdb/rocksdb/utilities/convenience/info_log_finder.cc +2 -2
  760. package/deps/rocksdb/rocksdb/utilities/counted_fs.cc +355 -0
  761. package/deps/rocksdb/rocksdb/utilities/counted_fs.h +152 -0
  762. package/deps/rocksdb/rocksdb/utilities/env_mirror.cc +13 -0
  763. package/deps/rocksdb/rocksdb/utilities/env_timed.cc +164 -122
  764. package/deps/rocksdb/rocksdb/utilities/env_timed.h +97 -0
  765. package/deps/rocksdb/rocksdb/utilities/fault_injection_env.cc +75 -17
  766. package/deps/rocksdb/rocksdb/utilities/fault_injection_env.h +19 -3
  767. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.cc +539 -126
  768. package/deps/rocksdb/rocksdb/utilities/fault_injection_fs.h +162 -17
  769. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.cc +110 -0
  770. package/deps/rocksdb/rocksdb/utilities/fault_injection_secondary_cache.h +94 -0
  771. package/deps/rocksdb/rocksdb/utilities/memory/memory_test.cc +5 -2
  772. package/deps/rocksdb/rocksdb/utilities/memory_allocators.h +104 -0
  773. package/deps/rocksdb/rocksdb/utilities/merge_operators/bytesxor.h +5 -3
  774. package/deps/rocksdb/rocksdb/utilities/merge_operators/max.cc +4 -1
  775. package/deps/rocksdb/rocksdb/utilities/merge_operators/put.cc +11 -3
  776. package/deps/rocksdb/rocksdb/utilities/merge_operators/sortlist.cc +0 -2
  777. package/deps/rocksdb/rocksdb/utilities/merge_operators/sortlist.h +5 -1
  778. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend.cc +29 -10
  779. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend.h +6 -3
  780. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend2.cc +29 -14
  781. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend2.h +6 -3
  782. package/deps/rocksdb/rocksdb/utilities/merge_operators/string_append/stringappend_test.cc +71 -18
  783. package/deps/rocksdb/rocksdb/utilities/merge_operators/uint64add.cc +15 -9
  784. package/deps/rocksdb/rocksdb/utilities/merge_operators.cc +120 -0
  785. package/deps/rocksdb/rocksdb/utilities/merge_operators.h +3 -23
  786. package/deps/rocksdb/rocksdb/utilities/object_registry.cc +267 -42
  787. package/deps/rocksdb/rocksdb/utilities/object_registry_test.cc +702 -76
  788. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration.cc +1 -1
  789. package/deps/rocksdb/rocksdb/utilities/option_change_migration/option_change_migration_test.cc +26 -5
  790. package/deps/rocksdb/rocksdb/utilities/options/options_util.cc +1 -1
  791. package/deps/rocksdb/rocksdb/utilities/options/options_util_test.cc +124 -1
  792. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier.cc +2 -3
  793. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier.h +8 -9
  794. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.cc +15 -13
  795. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_file.h +1 -1
  796. package/deps/rocksdb/rocksdb/utilities/persistent_cache/block_cache_tier_metadata.h +4 -4
  797. package/deps/rocksdb/rocksdb/utilities/persistent_cache/hash_table_evictable.h +2 -2
  798. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_bench.cc +8 -9
  799. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_test.cc +1 -1
  800. package/deps/rocksdb/rocksdb/utilities/persistent_cache/persistent_cache_tier.h +6 -3
  801. package/deps/rocksdb/rocksdb/utilities/persistent_cache/volatile_tier_impl.h +2 -2
  802. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator.cc +3 -0
  803. package/deps/rocksdb/rocksdb/utilities/simulator_cache/cache_simulator_test.cc +2 -0
  804. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache.cc +43 -35
  805. package/deps/rocksdb/rocksdb/utilities/simulator_cache/sim_cache_test.cc +20 -18
  806. package/deps/rocksdb/rocksdb/utilities/table_properties_collectors/compact_on_deletion_collector.cc +107 -2
  807. package/deps/rocksdb/rocksdb/utilities/trace/file_trace_reader_writer.cc +23 -15
  808. package/deps/rocksdb/rocksdb/utilities/trace/file_trace_reader_writer.h +2 -2
  809. package/deps/rocksdb/rocksdb/utilities/trace/replayer_impl.cc +316 -0
  810. package/deps/rocksdb/rocksdb/utilities/trace/replayer_impl.h +86 -0
  811. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.cc +4 -5
  812. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager.h +4 -3
  813. package/deps/rocksdb/rocksdb/utilities/transactions/lock/point/point_lock_manager_test.h +1 -1
  814. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_locking_test.cc +119 -3
  815. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/locktree.cc +20 -3
  816. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/locktree/locktree.h +20 -0
  817. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_external_pthread.h +3 -2
  818. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/lib/portability/toku_time.h +4 -0
  819. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_manager.cc +38 -14
  820. package/deps/rocksdb/rocksdb/utilities/transactions/lock/range/range_tree/range_tree_lock_manager.h +17 -10
  821. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_db_impl.h +1 -0
  822. package/deps/rocksdb/rocksdb/utilities/transactions/optimistic_transaction_test.cc +1 -2
  823. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.cc +423 -34
  824. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction.h +82 -2
  825. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.cc +72 -40
  826. package/deps/rocksdb/rocksdb/utilities/transactions/pessimistic_transaction_db.h +32 -1
  827. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.cc +13 -5
  828. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_base.h +7 -3
  829. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.cc +207 -43
  830. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_test.h +50 -7
  831. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_util.cc +28 -10
  832. package/deps/rocksdb/rocksdb/utilities/transactions/transaction_util.h +11 -6
  833. package/deps/rocksdb/rocksdb/utilities/transactions/write_committed_transaction_ts_test.cc +516 -0
  834. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_transaction_test.cc +506 -15
  835. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn.cc +27 -13
  836. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.cc +14 -14
  837. package/deps/rocksdb/rocksdb/utilities/transactions/write_prepared_txn_db.h +3 -0
  838. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_transaction_test.cc +2 -2
  839. package/deps/rocksdb/rocksdb/utilities/transactions/write_unprepared_txn.cc +14 -5
  840. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.cc +305 -27
  841. package/deps/rocksdb/rocksdb/utilities/ttl/db_ttl_impl.h +55 -159
  842. package/deps/rocksdb/rocksdb/utilities/ttl/ttl_test.cc +209 -2
  843. package/deps/rocksdb/rocksdb/utilities/wal_filter.cc +23 -0
  844. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index.cc +157 -88
  845. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.cc +501 -114
  846. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_internal.h +91 -316
  847. package/deps/rocksdb/rocksdb/utilities/write_batch_with_index/write_batch_with_index_test.cc +1212 -672
  848. package/deps/rocksdb/rocksdb.gyp +425 -446
  849. package/package.json +8 -8
  850. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  851. package/prebuilds/darwin-x86/node.napi.node +0 -0
  852. package/prebuilds/{darwin-x64+arm64 → linux-x64}/node.napi.node +0 -0
  853. package/deps/rocksdb/rocksdb/env/env_hdfs.cc +0 -648
  854. package/deps/rocksdb/rocksdb/hdfs/README +0 -23
  855. package/deps/rocksdb/rocksdb/hdfs/env_hdfs.h +0 -386
  856. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/backupable_db.h +0 -535
  857. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/env_librados.h +0 -175
  858. package/deps/rocksdb/rocksdb/include/rocksdb/utilities/utility_db.h +0 -34
  859. package/deps/rocksdb/rocksdb/memory/memkind_kmem_allocator_test.cc +0 -102
  860. package/deps/rocksdb/rocksdb/memtable/hash_linklist_rep.h +0 -49
  861. package/deps/rocksdb/rocksdb/memtable/hash_skiplist_rep.h +0 -44
  862. package/deps/rocksdb/rocksdb/options/customizable_helper.h +0 -216
  863. package/deps/rocksdb/rocksdb/third-party/folly/folly/CPortability.h +0 -27
  864. package/deps/rocksdb/rocksdb/third-party/folly/folly/ConstexprMath.h +0 -45
  865. package/deps/rocksdb/rocksdb/third-party/folly/folly/Indestructible.h +0 -166
  866. package/deps/rocksdb/rocksdb/third-party/folly/folly/Optional.h +0 -570
  867. package/deps/rocksdb/rocksdb/third-party/folly/folly/Portability.h +0 -92
  868. package/deps/rocksdb/rocksdb/third-party/folly/folly/ScopeGuard.h +0 -54
  869. package/deps/rocksdb/rocksdb/third-party/folly/folly/Traits.h +0 -152
  870. package/deps/rocksdb/rocksdb/third-party/folly/folly/Unit.h +0 -59
  871. package/deps/rocksdb/rocksdb/third-party/folly/folly/Utility.h +0 -141
  872. package/deps/rocksdb/rocksdb/third-party/folly/folly/chrono/Hardware.h +0 -33
  873. package/deps/rocksdb/rocksdb/third-party/folly/folly/container/Array.h +0 -74
  874. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex-inl.h +0 -117
  875. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex.cpp +0 -263
  876. package/deps/rocksdb/rocksdb/third-party/folly/folly/detail/Futex.h +0 -96
  877. package/deps/rocksdb/rocksdb/third-party/folly/folly/functional/Invoke.h +0 -40
  878. package/deps/rocksdb/rocksdb/third-party/folly/folly/hash/Hash.h +0 -29
  879. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Align.h +0 -144
  880. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Bits.h +0 -30
  881. package/deps/rocksdb/rocksdb/third-party/folly/folly/lang/Launder.h +0 -51
  882. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/Asm.h +0 -28
  883. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/SysSyscall.h +0 -10
  884. package/deps/rocksdb/rocksdb/third-party/folly/folly/portability/SysTypes.h +0 -26
  885. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification-inl.h +0 -138
  886. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification.cpp +0 -23
  887. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicNotification.h +0 -57
  888. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicUtil-inl.h +0 -260
  889. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/AtomicUtil.h +0 -52
  890. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/Baton.h +0 -328
  891. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex-inl.h +0 -1703
  892. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex.cpp +0 -16
  893. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutex.h +0 -304
  894. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/DistributedMutexSpecializations.h +0 -39
  895. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/ParkingLot.cpp +0 -26
  896. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/ParkingLot.h +0 -318
  897. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/WaitOptions.h +0 -57
  898. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/InlineFunctionRef.h +0 -219
  899. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/ProxyLockable-inl.h +0 -207
  900. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/ProxyLockable.h +0 -164
  901. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/Sleeper.h +0 -57
  902. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/detail/Spin.h +0 -77
  903. package/deps/rocksdb/rocksdb/third-party/folly/folly/synchronization/test/DistributedMutexTest.cpp +0 -1145
  904. package/deps/rocksdb/rocksdb/util/build_version.h +0 -15
  905. package/deps/rocksdb/rocksdb/util/xxh3p.h +0 -1392
  906. package/deps/rocksdb/rocksdb/utilities/backupable/backupable_db.cc +0 -2354
  907. package/deps/rocksdb/rocksdb/utilities/env_librados.cc +0 -1497
  908. package/deps/rocksdb/rocksdb/utilities/env_librados_test.cc +0 -1146
  909. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
@@ -9,44 +9,55 @@
9
9
 
10
10
  #if !defined(ROCKSDB_LITE) && !defined(OS_WIN)
11
11
 
12
- #include "rocksdb/utilities/backupable_db.h"
12
+ #include "rocksdb/utilities/backup_engine.h"
13
13
 
14
14
  #include <algorithm>
15
+ #include <array>
16
+ #include <atomic>
17
+ #include <cstddef>
18
+ #include <cstdint>
15
19
  #include <limits>
16
- #include <regex>
20
+ #include <memory>
21
+ #include <random>
17
22
  #include <string>
18
23
  #include <utility>
19
24
 
20
25
  #include "db/db_impl/db_impl.h"
26
+ #include "db/db_test_util.h"
27
+ #include "env/composite_env_wrapper.h"
21
28
  #include "env/env_chroot.h"
22
29
  #include "file/filename.h"
23
30
  #include "port/port.h"
24
31
  #include "port/stack_trace.h"
32
+ #include "rocksdb/advanced_options.h"
33
+ #include "rocksdb/env.h"
34
+ #include "rocksdb/file_checksum.h"
25
35
  #include "rocksdb/rate_limiter.h"
36
+ #include "rocksdb/statistics.h"
26
37
  #include "rocksdb/transaction_log.h"
27
38
  #include "rocksdb/types.h"
28
39
  #include "rocksdb/utilities/options_util.h"
40
+ #include "rocksdb/utilities/stackable_db.h"
29
41
  #include "test_util/sync_point.h"
30
42
  #include "test_util/testharness.h"
31
43
  #include "test_util/testutil.h"
32
44
  #include "util/cast_util.h"
33
45
  #include "util/mutexlock.h"
34
46
  #include "util/random.h"
47
+ #include "util/rate_limiter.h"
35
48
  #include "util/stderr_logger.h"
36
49
  #include "util/string_util.h"
50
+ #include "utilities/backup/backup_engine_impl.h"
37
51
 
38
52
  namespace ROCKSDB_NAMESPACE {
39
53
 
40
54
  namespace {
41
- using ShareFilesNaming = BackupableDBOptions::ShareFilesNaming;
55
+ using ShareFilesNaming = BackupEngineOptions::ShareFilesNaming;
42
56
  const auto kLegacyCrc32cAndFileSize =
43
- BackupableDBOptions::kLegacyCrc32cAndFileSize;
44
- const auto kUseDbSessionId = BackupableDBOptions::kUseDbSessionId;
45
- const auto kFlagIncludeFileSize = BackupableDBOptions::kFlagIncludeFileSize;
46
- const auto kFlagMatchInterimNaming =
47
- BackupableDBOptions::kFlagMatchInterimNaming;
48
- const auto kNamingDefault =
49
- kUseDbSessionId | kFlagIncludeFileSize | kFlagMatchInterimNaming;
57
+ BackupEngineOptions::kLegacyCrc32cAndFileSize;
58
+ const auto kUseDbSessionId = BackupEngineOptions::kUseDbSessionId;
59
+ const auto kFlagIncludeFileSize = BackupEngineOptions::kFlagIncludeFileSize;
60
+ const auto kNamingDefault = kUseDbSessionId | kFlagIncludeFileSize;
50
61
 
51
62
  class DummyDB : public StackableDB {
52
63
  public:
@@ -70,16 +81,6 @@ class DummyDB : public StackableDB {
70
81
 
71
82
  DBOptions GetDBOptions() const override { return DBOptions(options_); }
72
83
 
73
- using StackableDB::GetIntProperty;
74
- bool GetIntProperty(ColumnFamilyHandle*, const Slice& property,
75
- uint64_t* value) override {
76
- if (property == DB::Properties::kMinLogNumberToKeep) {
77
- *value = 1;
78
- return true;
79
- }
80
- return false;
81
- }
82
-
83
84
  Status EnableFileDeletions(bool /*force*/) override {
84
85
  EXPECT_TRUE(!deletions_enabled_);
85
86
  deletions_enabled_ = true;
@@ -92,53 +93,38 @@ class DummyDB : public StackableDB {
92
93
  return Status::OK();
93
94
  }
94
95
 
95
- Status GetLiveFiles(std::vector<std::string>& vec, uint64_t* mfs,
96
- bool /*flush_memtable*/ = true) override {
97
- EXPECT_TRUE(!deletions_enabled_);
98
- vec = live_files_;
99
- *mfs = 100;
100
- return Status::OK();
101
- }
102
-
103
96
  ColumnFamilyHandle* DefaultColumnFamily() const override { return nullptr; }
104
97
 
105
- class DummyLogFile : public LogFile {
106
- public:
107
- /* implicit */
108
- DummyLogFile(const std::string& path, bool alive = true)
109
- : path_(path), alive_(alive) {}
110
-
111
- std::string PathName() const override { return path_; }
112
-
113
- uint64_t LogNumber() const override {
114
- // what business do you have calling this method?
115
- ADD_FAILURE();
116
- return 0;
117
- }
118
-
119
- WalFileType Type() const override {
120
- return alive_ ? kAliveLogFile : kArchivedLogFile;
121
- }
122
-
123
- SequenceNumber StartSequence() const override {
124
- // this seqnum guarantees the dummy file will be included in the backup
125
- // as long as it is alive.
126
- return kMaxSequenceNumber;
127
- }
128
-
129
- uint64_t SizeFileBytes() const override { return 0; }
130
-
131
- private:
132
- std::string path_;
133
- bool alive_;
134
- }; // DummyLogFile
135
-
136
- Status GetSortedWalFiles(VectorLogPtr& files) override {
137
- EXPECT_TRUE(!deletions_enabled_);
138
- files.resize(wal_files_.size());
139
- for (size_t i = 0; i < files.size(); ++i) {
140
- files[i].reset(
141
- new DummyLogFile(wal_files_[i].first, wal_files_[i].second));
98
+ Status GetLiveFilesStorageInfo(
99
+ const LiveFilesStorageInfoOptions& opts,
100
+ std::vector<LiveFileStorageInfo>* files) override {
101
+ uint64_t number;
102
+ FileType type;
103
+ files->clear();
104
+ for (auto& f : live_files_) {
105
+ bool success = ParseFileName(f, &number, &type);
106
+ if (!success) {
107
+ return Status::InvalidArgument("Bad file name: " + f);
108
+ }
109
+ files->emplace_back();
110
+ LiveFileStorageInfo& info = files->back();
111
+ info.relative_filename = f;
112
+ info.directory = dbname_;
113
+ info.file_number = number;
114
+ info.file_type = type;
115
+ if (type == kDescriptorFile) {
116
+ info.size = 100; // See TestFs::GetChildrenFileAttributes below
117
+ info.trim_to_size = true;
118
+ } else if (type == kCurrentFile) {
119
+ info.size = 0;
120
+ info.trim_to_size = true;
121
+ } else {
122
+ info.size = 200; // See TestFs::GetChildrenFileAttributes below
123
+ }
124
+ if (opts.include_checksum_info) {
125
+ info.file_checksum = kUnknownFileChecksum;
126
+ info.file_checksum_func_name = kUnknownFileChecksumFuncName;
127
+ }
142
128
  }
143
129
  return Status::OK();
144
130
  }
@@ -147,8 +133,7 @@ class DummyDB : public StackableDB {
147
133
  Status FlushWAL(bool /*sync*/) override { return Status::OK(); }
148
134
 
149
135
  std::vector<std::string> live_files_;
150
- // pair<filename, alive?>
151
- std::vector<std::pair<std::string, bool>> wal_files_;
136
+
152
137
  private:
153
138
  Options options_;
154
139
  std::string dbname_;
@@ -156,17 +141,20 @@ class DummyDB : public StackableDB {
156
141
  mutable SequenceNumber sequence_number_;
157
142
  }; // DummyDB
158
143
 
159
- class TestEnv : public EnvWrapper {
144
+ class TestFs : public FileSystemWrapper {
160
145
  public:
161
- explicit TestEnv(Env* t) : EnvWrapper(t) {}
146
+ explicit TestFs(const std::shared_ptr<FileSystem>& t)
147
+ : FileSystemWrapper(t) {}
148
+ const char* Name() const override { return "TestFs"; }
162
149
 
163
- class DummySequentialFile : public SequentialFile {
150
+ class DummySequentialFile : public FSSequentialFile {
164
151
  public:
165
152
  explicit DummySequentialFile(bool fail_reads)
166
- : SequentialFile(), rnd_(5), fail_reads_(fail_reads) {}
167
- Status Read(size_t n, Slice* result, char* scratch) override {
153
+ : FSSequentialFile(), rnd_(5), fail_reads_(fail_reads) {}
154
+ IOStatus Read(size_t n, const IOOptions&, Slice* result, char* scratch,
155
+ IODebugContext*) override {
168
156
  if (fail_reads_) {
169
- return Status::IOError();
157
+ return IOStatus::IOError();
170
158
  }
171
159
  size_t read_size = (n > size_left) ? size_left : n;
172
160
  for (size_t i = 0; i < read_size; ++i) {
@@ -174,12 +162,12 @@ class TestEnv : public EnvWrapper {
174
162
  }
175
163
  *result = Slice(scratch, read_size);
176
164
  size_left -= read_size;
177
- return Status::OK();
165
+ return IOStatus::OK();
178
166
  }
179
167
 
180
- Status Skip(uint64_t n) override {
168
+ IOStatus Skip(uint64_t n) override {
181
169
  size_left = (n > size_left) ? size_left - n : 0;
182
- return Status::OK();
170
+ return IOStatus::OK();
183
171
  }
184
172
 
185
173
  private:
@@ -188,16 +176,16 @@ class TestEnv : public EnvWrapper {
188
176
  bool fail_reads_;
189
177
  };
190
178
 
191
- Status NewSequentialFile(const std::string& f,
192
- std::unique_ptr<SequentialFile>* r,
193
- const EnvOptions& options) override {
179
+ IOStatus NewSequentialFile(const std::string& f, const FileOptions& file_opts,
180
+ std::unique_ptr<FSSequentialFile>* r,
181
+ IODebugContext* dbg) override {
194
182
  MutexLock l(&mutex_);
195
183
  if (dummy_sequential_file_) {
196
184
  r->reset(
197
- new TestEnv::DummySequentialFile(dummy_sequential_file_fail_reads_));
198
- return Status::OK();
185
+ new TestFs::DummySequentialFile(dummy_sequential_file_fail_reads_));
186
+ return IOStatus::OK();
199
187
  } else {
200
- Status s = EnvWrapper::NewSequentialFile(f, r, options);
188
+ IOStatus s = FileSystemWrapper::NewSequentialFile(f, file_opts, r, dbg);
201
189
  if (s.ok()) {
202
190
  if ((*r)->use_direct_io()) {
203
191
  ++num_direct_seq_readers_;
@@ -208,15 +196,16 @@ class TestEnv : public EnvWrapper {
208
196
  }
209
197
  }
210
198
 
211
- Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
212
- const EnvOptions& options) override {
199
+ IOStatus NewWritableFile(const std::string& f, const FileOptions& file_opts,
200
+ std::unique_ptr<FSWritableFile>* r,
201
+ IODebugContext* dbg) override {
213
202
  MutexLock l(&mutex_);
214
203
  written_files_.push_back(f);
215
- if (limit_written_files_ <= 0) {
216
- return Status::NotSupported("Sorry, can't do this");
204
+ if (limit_written_files_ == 0) {
205
+ return IOStatus::NotSupported("Limit on written files reached");
217
206
  }
218
207
  limit_written_files_--;
219
- Status s = EnvWrapper::NewWritableFile(f, r, options);
208
+ IOStatus s = FileSystemWrapper::NewWritableFile(f, file_opts, r, dbg);
220
209
  if (s.ok()) {
221
210
  if ((*r)->use_direct_io()) {
222
211
  ++num_direct_writers_;
@@ -226,13 +215,14 @@ class TestEnv : public EnvWrapper {
226
215
  return s;
227
216
  }
228
217
 
229
- Status NewRandomAccessFile(const std::string& fname,
230
- std::unique_ptr<RandomAccessFile>* result,
231
- const EnvOptions& options) override {
218
+ IOStatus NewRandomAccessFile(const std::string& f,
219
+ const FileOptions& file_opts,
220
+ std::unique_ptr<FSRandomAccessFile>* r,
221
+ IODebugContext* dbg) override {
232
222
  MutexLock l(&mutex_);
233
- Status s = EnvWrapper::NewRandomAccessFile(fname, result, options);
223
+ IOStatus s = FileSystemWrapper::NewRandomAccessFile(f, file_opts, r, dbg);
234
224
  if (s.ok()) {
235
- if ((*result)->use_direct_io()) {
225
+ if ((*r)->use_direct_io()) {
236
226
  ++num_direct_rand_readers_;
237
227
  }
238
228
  ++num_rand_readers_;
@@ -240,22 +230,24 @@ class TestEnv : public EnvWrapper {
240
230
  return s;
241
231
  }
242
232
 
243
- Status DeleteFile(const std::string& fname) override {
233
+ IOStatus DeleteFile(const std::string& f, const IOOptions& options,
234
+ IODebugContext* dbg) override {
244
235
  MutexLock l(&mutex_);
245
236
  if (fail_delete_files_) {
246
- return Status::IOError();
237
+ return IOStatus::IOError();
247
238
  }
248
239
  EXPECT_GT(limit_delete_files_, 0U);
249
240
  limit_delete_files_--;
250
- return EnvWrapper::DeleteFile(fname);
241
+ return FileSystemWrapper::DeleteFile(f, options, dbg);
251
242
  }
252
243
 
253
- Status DeleteDir(const std::string& dirname) override {
244
+ IOStatus DeleteDir(const std::string& d, const IOOptions& options,
245
+ IODebugContext* dbg) override {
254
246
  MutexLock l(&mutex_);
255
247
  if (fail_delete_files_) {
256
- return Status::IOError();
248
+ return IOStatus::IOError();
257
249
  }
258
- return EnvWrapper::DeleteDir(dirname);
250
+ return FileSystemWrapper::DeleteDir(d, options, dbg);
259
251
  }
260
252
 
261
253
  void AssertWrittenFiles(std::vector<std::string>& should_have_written) {
@@ -296,12 +288,13 @@ class TestEnv : public EnvWrapper {
296
288
  }
297
289
 
298
290
  void SetGetChildrenFailure(bool fail) { get_children_failure_ = fail; }
299
- Status GetChildren(const std::string& dir,
300
- std::vector<std::string>* r) override {
291
+ IOStatus GetChildren(const std::string& dir, const IOOptions& io_opts,
292
+ std::vector<std::string>* r,
293
+ IODebugContext* dbg) override {
301
294
  if (get_children_failure_) {
302
- return Status::IOError("SimulatedFailure");
295
+ return IOStatus::IOError("SimulatedFailure");
303
296
  }
304
- return EnvWrapper::GetChildren(dir, r);
297
+ return FileSystemWrapper::GetChildren(dir, io_opts, r, dbg);
305
298
  }
306
299
 
307
300
  // Some test cases do not actually create the test files (e.g., see
@@ -310,54 +303,61 @@ class TestEnv : public EnvWrapper {
310
303
  void SetFilenamesForMockedAttrs(const std::vector<std::string>& filenames) {
311
304
  filenames_for_mocked_attrs_ = filenames;
312
305
  }
313
- Status GetChildrenFileAttributes(
314
- const std::string& dir, std::vector<Env::FileAttributes>* r) override {
306
+ IOStatus GetChildrenFileAttributes(const std::string& dir,
307
+ const IOOptions& options,
308
+ std::vector<FileAttributes>* result,
309
+ IODebugContext* dbg) override {
315
310
  if (filenames_for_mocked_attrs_.size() > 0) {
316
311
  for (const auto& filename : filenames_for_mocked_attrs_) {
317
- uint64_t size_bytes = 200; // Match TestEnv
312
+ uint64_t size_bytes = 200; // Match TestFs
318
313
  if (filename.find("MANIFEST") == 0) {
319
314
  size_bytes = 100; // Match DummyDB::GetLiveFiles
320
315
  }
321
- r->push_back({dir + filename, size_bytes});
316
+ result->push_back({dir + "/" + filename, size_bytes});
322
317
  }
323
- return Status::OK();
318
+ return IOStatus::OK();
324
319
  }
325
- return EnvWrapper::GetChildrenFileAttributes(dir, r);
320
+ return FileSystemWrapper::GetChildrenFileAttributes(dir, options, result,
321
+ dbg);
326
322
  }
327
- Status GetFileSize(const std::string& path, uint64_t* size_bytes) override {
323
+
324
+ IOStatus GetFileSize(const std::string& f, const IOOptions& options,
325
+ uint64_t* s, IODebugContext* dbg) override {
328
326
  if (filenames_for_mocked_attrs_.size() > 0) {
329
- auto fname = path.substr(path.find_last_of('/'));
327
+ auto fname = f.substr(f.find_last_of('/') + 1);
330
328
  auto filename_iter = std::find(filenames_for_mocked_attrs_.begin(),
331
329
  filenames_for_mocked_attrs_.end(), fname);
332
330
  if (filename_iter != filenames_for_mocked_attrs_.end()) {
333
- *size_bytes = 200; // Match TestEnv
331
+ *s = 200; // Match TestFs
334
332
  if (fname.find("MANIFEST") == 0) {
335
- *size_bytes = 100; // Match DummyDB::GetLiveFiles
333
+ *s = 100; // Match DummyDB::GetLiveFiles
336
334
  }
337
- return Status::OK();
335
+ return IOStatus::OK();
338
336
  }
339
- return Status::NotFound(fname);
337
+ return IOStatus::NotFound(fname);
340
338
  }
341
- return EnvWrapper::GetFileSize(path, size_bytes);
339
+ return FileSystemWrapper::GetFileSize(f, options, s, dbg);
342
340
  }
343
341
 
344
342
  void SetCreateDirIfMissingFailure(bool fail) {
345
343
  create_dir_if_missing_failure_ = fail;
346
344
  }
347
- Status CreateDirIfMissing(const std::string& d) override {
345
+ IOStatus CreateDirIfMissing(const std::string& d, const IOOptions& options,
346
+ IODebugContext* dbg) override {
348
347
  if (create_dir_if_missing_failure_) {
349
- return Status::IOError("SimulatedFailure");
348
+ return IOStatus::IOError("SimulatedFailure");
350
349
  }
351
- return EnvWrapper::CreateDirIfMissing(d);
350
+ return FileSystemWrapper::CreateDirIfMissing(d, options, dbg);
352
351
  }
353
352
 
354
353
  void SetNewDirectoryFailure(bool fail) { new_directory_failure_ = fail; }
355
- Status NewDirectory(const std::string& name,
356
- std::unique_ptr<Directory>* result) override {
354
+ IOStatus NewDirectory(const std::string& name, const IOOptions& io_opts,
355
+ std::unique_ptr<FSDirectory>* result,
356
+ IODebugContext* dbg) override {
357
357
  if (new_directory_failure_) {
358
- return Status::IOError("SimulatedFailure");
358
+ return IOStatus::IOError("SimulatedFailure");
359
359
  }
360
- return EnvWrapper::NewDirectory(name, result);
360
+ return FileSystemWrapper::NewDirectory(name, io_opts, result, dbg);
361
361
  }
362
362
 
363
363
  void ClearFileOpenCounters() {
@@ -375,6 +375,7 @@ class TestEnv : public EnvWrapper {
375
375
  int num_seq_readers() { return num_seq_readers_; }
376
376
  int num_direct_seq_readers() { return num_direct_seq_readers_; }
377
377
  int num_writers() { return num_writers_; }
378
+ // FIXME(?): unused
378
379
  int num_direct_writers() { return num_direct_writers_; }
379
380
 
380
381
  private:
@@ -393,17 +394,18 @@ class TestEnv : public EnvWrapper {
393
394
 
394
395
  // Keeps track of how many files of each type were successfully opened, and
395
396
  // out of those, how many were opened with direct I/O.
396
- std::atomic<int> num_rand_readers_;
397
- std::atomic<int> num_direct_rand_readers_;
398
- std::atomic<int> num_seq_readers_;
399
- std::atomic<int> num_direct_seq_readers_;
400
- std::atomic<int> num_writers_;
401
- std::atomic<int> num_direct_writers_;
402
- }; // TestEnv
397
+ std::atomic<int> num_rand_readers_{};
398
+ std::atomic<int> num_direct_rand_readers_{};
399
+ std::atomic<int> num_seq_readers_{};
400
+ std::atomic<int> num_direct_seq_readers_{};
401
+ std::atomic<int> num_writers_{};
402
+ std::atomic<int> num_direct_writers_{};
403
+ }; // TestFs
403
404
 
404
405
  class FileManager : public EnvWrapper {
405
406
  public:
406
407
  explicit FileManager(Env* t) : EnvWrapper(t), rnd_(5) {}
408
+ const char* Name() const override { return "FileManager"; }
407
409
 
408
410
  Status GetRandomFileInDir(const std::string& dir, std::string* fname,
409
411
  uint64_t* fsize) {
@@ -598,7 +600,7 @@ void AssertEmpty(DB* db, int from, int to) {
598
600
  }
599
601
  } // namespace
600
602
 
601
- class BackupableDBTest : public testing::Test {
603
+ class BackupEngineTest : public testing::Test {
602
604
  public:
603
605
  enum ShareOption {
604
606
  kNoShare,
@@ -609,47 +611,78 @@ class BackupableDBTest : public testing::Test {
609
611
  const std::vector<ShareOption> kAllShareOptions = {
610
612
  kNoShare, kShareNoChecksum, kShareWithChecksum};
611
613
 
612
- BackupableDBTest() {
614
+ BackupEngineTest() {
613
615
  // set up files
614
- std::string db_chroot = test::PerThreadDBPath("backupable_db");
615
- std::string backup_chroot = test::PerThreadDBPath("backupable_db_backup");
616
+ std::string db_chroot = test::PerThreadDBPath("db_for_backup");
617
+ std::string backup_chroot = test::PerThreadDBPath("db_backups");
616
618
  EXPECT_OK(Env::Default()->CreateDirIfMissing(db_chroot));
617
619
  EXPECT_OK(Env::Default()->CreateDirIfMissing(backup_chroot));
618
620
  dbname_ = "/tempdb";
619
621
  backupdir_ = "/tempbk";
622
+ latest_backup_ = backupdir_ + "/LATEST_BACKUP";
620
623
 
621
- // set up envs
622
- db_chroot_env_.reset(NewChrootEnv(Env::Default(), db_chroot));
623
- backup_chroot_env_.reset(NewChrootEnv(Env::Default(), backup_chroot));
624
- test_db_env_.reset(new TestEnv(db_chroot_env_.get()));
625
- test_backup_env_.reset(new TestEnv(backup_chroot_env_.get()));
626
- file_manager_.reset(new FileManager(backup_chroot_env_.get()));
627
- db_file_manager_.reset(new FileManager(db_chroot_env_.get()));
624
+ // set up FileSystem & Envs
625
+ db_chroot_fs_ = NewChrootFileSystem(FileSystem::Default(), db_chroot);
626
+ backup_chroot_fs_ =
627
+ NewChrootFileSystem(FileSystem::Default(), backup_chroot);
628
+ test_db_fs_ = std::make_shared<TestFs>(db_chroot_fs_);
629
+ test_backup_fs_ = std::make_shared<TestFs>(backup_chroot_fs_);
630
+ SetEnvsFromFileSystems();
628
631
 
629
632
  // set up db options
630
633
  options_.create_if_missing = true;
631
634
  options_.paranoid_checks = true;
632
635
  options_.write_buffer_size = 1 << 17; // 128KB
633
- options_.env = test_db_env_.get();
634
636
  options_.wal_dir = dbname_;
635
-
636
- // Create logger
637
- DBOptions logger_options;
638
- logger_options.env = db_chroot_env_.get();
639
- // TODO: This should really be an EXPECT_OK, but this CreateLogger fails
640
- // regularly in some environments with "no such directory"
641
- CreateLoggerFromOptions(dbname_, logger_options, &logger_)
642
- .PermitUncheckedError();
637
+ options_.enable_blob_files = true;
638
+
639
+ // The sync option is not easily testable in unit tests, but should be
640
+ // smoke tested across all the other backup tests. However, it is
641
+ // certainly not worth doubling the runtime of backup tests for it.
642
+ // Thus, we can enable sync for one of our alternate testing
643
+ // configurations.
644
+ constexpr bool kUseSync =
645
+ #ifdef ROCKSDB_MODIFY_NPHASH
646
+ true;
647
+ #else
648
+ false;
649
+ #endif // ROCKSDB_MODIFY_NPHASH
643
650
 
644
651
  // set up backup db options
645
- backupable_options_.reset(new BackupableDBOptions(
646
- backupdir_, test_backup_env_.get(), true, logger_.get(), true));
652
+ engine_options_.reset(new BackupEngineOptions(
653
+ backupdir_, test_backup_env_.get(), /*share_table_files*/ true,
654
+ logger_.get(), kUseSync));
647
655
 
648
656
  // most tests will use multi-threaded backups
649
- backupable_options_->max_background_operations = 7;
657
+ engine_options_->max_background_operations = 7;
650
658
 
651
659
  // delete old files in db
652
660
  DestroyDB(dbname_, options_);
661
+
662
+ // delete old LATEST_BACKUP file, which some tests create for compatibility
663
+ // testing.
664
+ backup_chroot_env_->DeleteFile(latest_backup_).PermitUncheckedError();
665
+ }
666
+
667
+ void SetEnvsFromFileSystems() {
668
+ db_chroot_env_.reset(
669
+ new CompositeEnvWrapper(Env::Default(), db_chroot_fs_));
670
+ backup_chroot_env_.reset(
671
+ new CompositeEnvWrapper(Env::Default(), backup_chroot_fs_));
672
+ test_db_env_.reset(new CompositeEnvWrapper(Env::Default(), test_db_fs_));
673
+ options_.env = test_db_env_.get();
674
+ test_backup_env_.reset(
675
+ new CompositeEnvWrapper(Env::Default(), test_backup_fs_));
676
+ if (engine_options_) {
677
+ engine_options_->backup_env = test_backup_env_.get();
678
+ }
679
+ file_manager_.reset(new FileManager(backup_chroot_env_.get()));
680
+ db_file_manager_.reset(new FileManager(db_chroot_env_.get()));
681
+
682
+ // Create logger
683
+ DBOptions logger_options;
684
+ logger_options.env = db_chroot_env_.get();
685
+ ASSERT_OK(CreateLoggerFromOptions(dbname_, logger_options, &logger_));
653
686
  }
654
687
 
655
688
  DB* OpenDB() {
@@ -658,21 +691,25 @@ class BackupableDBTest : public testing::Test {
658
691
  return db;
659
692
  }
660
693
 
661
- void CloseAndReopenDB() {
694
+ void CloseAndReopenDB(bool read_only = false) {
662
695
  // Close DB
663
696
  db_.reset();
664
697
 
665
698
  // Open DB
666
- test_db_env_->SetLimitWrittenFiles(1000000);
699
+ test_db_fs_->SetLimitWrittenFiles(1000000);
667
700
  DB* db;
668
- ASSERT_OK(DB::Open(options_, dbname_, &db));
701
+ if (read_only) {
702
+ ASSERT_OK(DB::OpenForReadOnly(options_, dbname_, &db));
703
+ } else {
704
+ ASSERT_OK(DB::Open(options_, dbname_, &db));
705
+ }
669
706
  db_.reset(db);
670
707
  }
671
708
 
672
709
  void InitializeDBAndBackupEngine(bool dummy = false) {
673
710
  // reset all the db env defaults
674
- test_db_env_->SetLimitWrittenFiles(1000000);
675
- test_db_env_->SetDummySequentialFile(dummy);
711
+ test_db_fs_->SetLimitWrittenFiles(1000000);
712
+ test_db_fs_->SetDummySequentialFile(dummy);
676
713
 
677
714
  DB* db;
678
715
  if (dummy) {
@@ -689,10 +726,10 @@ class BackupableDBTest : public testing::Test {
689
726
  ShareOption shared_option = kShareNoChecksum) {
690
727
  InitializeDBAndBackupEngine(dummy);
691
728
  // reset backup env defaults
692
- test_backup_env_->SetLimitWrittenFiles(1000000);
693
- backupable_options_->destroy_old_data = destroy_old_data;
694
- backupable_options_->share_table_files = shared_option != kNoShare;
695
- backupable_options_->share_files_with_checksum =
729
+ test_backup_fs_->SetLimitWrittenFiles(1000000);
730
+ engine_options_->destroy_old_data = destroy_old_data;
731
+ engine_options_->share_table_files = shared_option != kNoShare;
732
+ engine_options_->share_files_with_checksum =
696
733
  shared_option == kShareWithChecksum;
697
734
  OpenBackupEngine(destroy_old_data);
698
735
  }
@@ -703,15 +740,79 @@ class BackupableDBTest : public testing::Test {
703
740
  }
704
741
 
705
742
  void OpenBackupEngine(bool destroy_old_data = false) {
706
- backupable_options_->destroy_old_data = destroy_old_data;
743
+ engine_options_->destroy_old_data = destroy_old_data;
744
+ engine_options_->info_log = logger_.get();
707
745
  BackupEngine* backup_engine;
708
- ASSERT_OK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
746
+ ASSERT_OK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
709
747
  &backup_engine));
710
748
  backup_engine_.reset(backup_engine);
711
749
  }
712
750
 
713
751
  void CloseBackupEngine() { backup_engine_.reset(nullptr); }
714
752
 
753
+ // cross-cutting test of GetBackupInfo
754
+ void AssertBackupInfoConsistency() {
755
+ std::vector<BackupInfo> backup_info;
756
+ backup_engine_->GetBackupInfo(&backup_info, /*with file details*/ true);
757
+ std::map<std::string, uint64_t> file_sizes;
758
+
759
+ // Find the files that are supposed to be there
760
+ for (auto& backup : backup_info) {
761
+ uint64_t sum_for_backup = 0;
762
+ for (auto& file : backup.file_details) {
763
+ auto e = file_sizes.find(file.relative_filename);
764
+ if (e == file_sizes.end()) {
765
+ // fprintf(stderr, "Adding %s -> %u\n",
766
+ // file.relative_filename.c_str(), (unsigned)file.size);
767
+ file_sizes[file.relative_filename] = file.size;
768
+ } else {
769
+ ASSERT_EQ(file_sizes[file.relative_filename], file.size);
770
+ }
771
+ sum_for_backup += file.size;
772
+ }
773
+ ASSERT_EQ(backup.size, sum_for_backup);
774
+ }
775
+
776
+ std::vector<BackupID> corrupt_backup_ids;
777
+ backup_engine_->GetCorruptedBackups(&corrupt_backup_ids);
778
+ bool has_corrupt = corrupt_backup_ids.size() > 0;
779
+
780
+ // Compare with what's in backup dir
781
+ std::vector<std::string> child_dirs;
782
+ ASSERT_OK(
783
+ test_backup_env_->GetChildren(backupdir_ + "/private", &child_dirs));
784
+ for (auto& dir : child_dirs) {
785
+ dir = "private/" + dir;
786
+ }
787
+ child_dirs.push_back("shared"); // might not exist
788
+ child_dirs.push_back("shared_checksum"); // might not exist
789
+ for (auto& dir : child_dirs) {
790
+ std::vector<std::string> children;
791
+ test_backup_env_->GetChildren(backupdir_ + "/" + dir, &children)
792
+ .PermitUncheckedError();
793
+ // fprintf(stderr, "ls %s\n", (backupdir_ + "/" + dir).c_str());
794
+ for (auto& file : children) {
795
+ uint64_t size;
796
+ size = UINT64_MAX; // appease clang-analyze
797
+ std::string rel_file = dir + "/" + file;
798
+ // fprintf(stderr, "stat %s\n", (backupdir_ + "/" + rel_file).c_str());
799
+ ASSERT_OK(
800
+ test_backup_env_->GetFileSize(backupdir_ + "/" + rel_file, &size));
801
+ auto e = file_sizes.find(rel_file);
802
+ if (e == file_sizes.end()) {
803
+ // The only case in which we should find files not reported
804
+ ASSERT_TRUE(has_corrupt);
805
+ } else {
806
+ ASSERT_EQ(e->second, size);
807
+ file_sizes.erase(e);
808
+ }
809
+ }
810
+ }
811
+
812
+ // Everything should have been matched
813
+ ASSERT_EQ(file_sizes.size(), 0);
814
+ }
815
+
715
816
  // restores backup backup_id and asserts the existence of
716
817
  // [start_exist, end_exist> and not-existence of
717
818
  // [end_exist, end>
@@ -727,6 +828,9 @@ class BackupableDBTest : public testing::Test {
727
828
  opened_backup_engine = true;
728
829
  OpenBackupEngine();
729
830
  }
831
+ AssertBackupInfoConsistency();
832
+
833
+ // Now perform restore
730
834
  if (backup_id > 0) {
731
835
  ASSERT_OK(backup_engine_->RestoreDBFromBackup(backup_id, dbname_, dbname_,
732
836
  restore_options));
@@ -735,6 +839,7 @@ class BackupableDBTest : public testing::Test {
735
839
  restore_options));
736
840
  }
737
841
  DB* db = OpenDB();
842
+ // Check DB contents
738
843
  AssertExists(db, start_exist, end_exist);
739
844
  if (end != 0) {
740
845
  AssertEmpty(db, end_exist, end);
@@ -758,41 +863,51 @@ class BackupableDBTest : public testing::Test {
758
863
  }
759
864
  }
760
865
 
761
- Status GetTableFilesInDB(std::vector<FileAttributes>* table_files) {
866
+ Status GetDataFilesInDB(const FileType& file_type,
867
+ std::vector<FileAttributes>* files) {
868
+ std::vector<std::string> live;
869
+ uint64_t ignore_manifest_size;
870
+ Status s = db_->GetLiveFiles(live, &ignore_manifest_size, /*flush*/ false);
871
+ if (!s.ok()) {
872
+ return s;
873
+ }
762
874
  std::vector<FileAttributes> children;
763
- Status s = test_db_env_->GetChildrenFileAttributes(dbname_, &children);
875
+ s = test_db_env_->GetChildrenFileAttributes(dbname_, &children);
764
876
  for (const auto& child : children) {
765
- if (child.size_bytes > 0 && child.name.size() > 4 &&
766
- child.name.rfind(".sst") == child.name.length() - 4) {
767
- table_files->push_back(child);
877
+ FileType type;
878
+ uint64_t number = 0;
879
+ if (ParseFileName(child.name, &number, &type) && type == file_type &&
880
+ std::find(live.begin(), live.end(), "/" + child.name) != live.end()) {
881
+ files->push_back(child);
768
882
  }
769
883
  }
770
884
  return s;
771
885
  }
772
886
 
773
- Status GetRandomTableFileInDB(std::string* fname_out,
774
- uint64_t* fsize_out = nullptr) {
887
+ Status GetRandomDataFileInDB(const FileType& file_type,
888
+ std::string* fname_out,
889
+ uint64_t* fsize_out = nullptr) {
775
890
  Random rnd(6); // NB: hardly "random"
776
- std::vector<FileAttributes> table_files;
777
- Status s = GetTableFilesInDB(&table_files);
891
+ std::vector<FileAttributes> files;
892
+ Status s = GetDataFilesInDB(file_type, &files);
778
893
  if (!s.ok()) {
779
894
  return s;
780
895
  }
781
- if (table_files.empty()) {
896
+ if (files.empty()) {
782
897
  return Status::NotFound("");
783
898
  }
784
- size_t i = rnd.Uniform(static_cast<int>(table_files.size()));
785
- *fname_out = dbname_ + "/" + table_files[i].name;
899
+ size_t i = rnd.Uniform(static_cast<int>(files.size()));
900
+ *fname_out = dbname_ + "/" + files[i].name;
786
901
  if (fsize_out) {
787
- *fsize_out = table_files[i].size_bytes;
902
+ *fsize_out = files[i].size_bytes;
788
903
  }
789
904
  return Status::OK();
790
905
  }
791
906
 
792
- Status CorruptRandomTableFileInDB() {
907
+ Status CorruptRandomDataFileInDB(const FileType& file_type) {
793
908
  std::string fname;
794
909
  uint64_t fsize = 0;
795
- Status s = GetRandomTableFileInDB(&fname, &fsize);
910
+ Status s = GetRandomDataFileInDB(file_type, &fname, &fsize);
796
911
  if (!s.ok()) {
797
912
  return s;
798
913
  }
@@ -812,15 +927,17 @@ class BackupableDBTest : public testing::Test {
812
927
  }
813
928
 
814
929
  void AssertDirectoryFilesMatchRegex(const std::string& dir,
815
- const std::regex& pattern,
930
+ const TestRegex& pattern,
931
+ const std::string& file_type,
816
932
  int minimum_count) {
817
933
  std::vector<FileAttributes> children;
818
934
  ASSERT_OK(file_manager_->GetChildrenFileAttributes(dir, &children));
819
935
  int found_count = 0;
820
936
  for (const auto& child : children) {
821
- const std::string match("match");
822
- ASSERT_EQ(match, std::regex_replace(child.name, pattern, match));
823
- ++found_count;
937
+ if (EndsWith(child.name, file_type)) {
938
+ ASSERT_MATCHES_REGEX(child.name, pattern);
939
+ ++found_count;
940
+ }
824
941
  }
825
942
  ASSERT_GE(found_count, minimum_count);
826
943
  }
@@ -847,21 +964,28 @@ class BackupableDBTest : public testing::Test {
847
964
  // files
848
965
  std::string dbname_;
849
966
  std::string backupdir_;
967
+ std::string latest_backup_;
850
968
 
851
969
  // logger_ must be above backup_engine_ such that the engine's destructor,
852
970
  // which uses a raw pointer to the logger, executes first.
853
971
  std::shared_ptr<Logger> logger_;
854
972
 
855
- // envs
973
+ // FileSystems
974
+ std::shared_ptr<FileSystem> db_chroot_fs_;
975
+ std::shared_ptr<FileSystem> backup_chroot_fs_;
976
+ std::shared_ptr<TestFs> test_db_fs_;
977
+ std::shared_ptr<TestFs> test_backup_fs_;
978
+
979
+ // Env wrappers
856
980
  std::unique_ptr<Env> db_chroot_env_;
857
981
  std::unique_ptr<Env> backup_chroot_env_;
858
- std::unique_ptr<TestEnv> test_db_env_;
859
- std::unique_ptr<TestEnv> test_backup_env_;
982
+ std::unique_ptr<Env> test_db_env_;
983
+ std::unique_ptr<Env> test_backup_env_;
860
984
  std::unique_ptr<FileManager> file_manager_;
861
985
  std::unique_ptr<FileManager> db_file_manager_;
862
986
 
863
987
  // all the dbs!
864
- DummyDB* dummy_db_; // BackupableDB owns dummy_db_
988
+ DummyDB* dummy_db_; // owned as db_ when present
865
989
  std::unique_ptr<DB> db_;
866
990
  std::unique_ptr<BackupEngine> backup_engine_;
867
991
 
@@ -869,8 +993,8 @@ class BackupableDBTest : public testing::Test {
869
993
  Options options_;
870
994
 
871
995
  protected:
872
- std::unique_ptr<BackupableDBOptions> backupable_options_;
873
- }; // BackupableDBTest
996
+ std::unique_ptr<BackupEngineOptions> engine_options_;
997
+ }; // BackupEngineTest
874
998
 
875
999
  void AppendPath(const std::string& path, std::vector<std::string>& v) {
876
1000
  for (auto& f : v) {
@@ -878,43 +1002,45 @@ void AppendPath(const std::string& path, std::vector<std::string>& v) {
878
1002
  }
879
1003
  }
880
1004
 
881
- class BackupableDBTestWithParam : public BackupableDBTest,
1005
+ class BackupEngineTestWithParam : public BackupEngineTest,
882
1006
  public testing::WithParamInterface<bool> {
883
1007
  public:
884
- BackupableDBTestWithParam() {
885
- backupable_options_->share_files_with_checksum = GetParam();
1008
+ BackupEngineTestWithParam() {
1009
+ engine_options_->share_files_with_checksum = GetParam();
886
1010
  }
887
1011
  void OpenDBAndBackupEngine(
888
1012
  bool destroy_old_data = false, bool dummy = false,
889
1013
  ShareOption shared_option = kShareNoChecksum) override {
890
- BackupableDBTest::InitializeDBAndBackupEngine(dummy);
1014
+ BackupEngineTest::InitializeDBAndBackupEngine(dummy);
891
1015
  // reset backup env defaults
892
- test_backup_env_->SetLimitWrittenFiles(1000000);
893
- backupable_options_->destroy_old_data = destroy_old_data;
894
- backupable_options_->share_table_files = shared_option != kNoShare;
1016
+ test_backup_fs_->SetLimitWrittenFiles(1000000);
1017
+ engine_options_->destroy_old_data = destroy_old_data;
1018
+ engine_options_->share_table_files = shared_option != kNoShare;
895
1019
  // NOTE: keep share_files_with_checksum setting from constructor
896
1020
  OpenBackupEngine(destroy_old_data);
897
1021
  }
898
1022
  };
899
1023
 
900
- TEST_F(BackupableDBTest, FileCollision) {
901
- const int keys_iteration = 5000;
1024
+ TEST_F(BackupEngineTest, FileCollision) {
1025
+ const int keys_iteration = 100;
902
1026
  for (const auto& sopt : kAllShareOptions) {
903
1027
  OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */, sopt);
904
1028
  FillDB(db_.get(), 0, keys_iteration);
905
1029
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
906
- FillDB(db_.get(), 0, keys_iteration);
1030
+ FillDB(db_.get(), keys_iteration, keys_iteration * 2);
907
1031
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
908
1032
  CloseDBAndBackupEngine();
909
1033
 
910
1034
  // If the db directory has been cleaned up, it is sensitive to file
911
1035
  // collision.
912
- DestroyDB(dbname_, options_);
1036
+ ASSERT_OK(DestroyDB(dbname_, options_));
913
1037
 
914
- // open with old backup
1038
+ // open fresh DB, but old backups present
915
1039
  OpenDBAndBackupEngine(false /* destroy_old_data */, false /* dummy */,
916
1040
  sopt);
917
- FillDB(db_.get(), 0, keys_iteration * 2);
1041
+ FillDB(db_.get(), 0, keys_iteration);
1042
+ ASSERT_OK(db_->Flush(FlushOptions())); // like backup would do
1043
+ FillDB(db_.get(), keys_iteration, keys_iteration * 2);
918
1044
  if (sopt != kShareNoChecksum) {
919
1045
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
920
1046
  } else {
@@ -928,13 +1054,13 @@ TEST_F(BackupableDBTest, FileCollision) {
928
1054
  CloseDBAndBackupEngine();
929
1055
 
930
1056
  // delete old data
931
- DestroyDB(dbname_, options_);
1057
+ ASSERT_OK(DestroyDB(dbname_, options_));
932
1058
  }
933
1059
  }
934
1060
 
935
1061
  // This test verifies that the verifyBackup method correctly identifies
936
1062
  // invalid backups
937
- TEST_P(BackupableDBTestWithParam, VerifyBackup) {
1063
+ TEST_P(BackupEngineTestWithParam, VerifyBackup) {
938
1064
  const int keys_iteration = 5000;
939
1065
  OpenDBAndBackupEngine(true);
940
1066
  // create five backups
@@ -963,8 +1089,9 @@ TEST_P(BackupableDBTestWithParam, VerifyBackup) {
963
1089
  CloseDBAndBackupEngine();
964
1090
  }
965
1091
 
1092
+ #if !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
966
1093
  // open DB, write, close DB, backup, restore, repeat
967
- TEST_P(BackupableDBTestWithParam, OfflineIntegrationTest) {
1094
+ TEST_P(BackupEngineTestWithParam, OfflineIntegrationTest) {
968
1095
  // has to be a big number, so that it triggers the memtable flush
969
1096
  const int keys_iteration = 5000;
970
1097
  const int max_key = keys_iteration * 4 + 10;
@@ -1012,7 +1139,7 @@ TEST_P(BackupableDBTestWithParam, OfflineIntegrationTest) {
1012
1139
  }
1013
1140
 
1014
1141
  // open DB, write, backup, write, backup, close, restore
1015
- TEST_P(BackupableDBTestWithParam, OnlineIntegrationTest) {
1142
+ TEST_P(BackupEngineTestWithParam, OnlineIntegrationTest) {
1016
1143
  // has to be a big number, so that it triggers the memtable flush
1017
1144
  const int keys_iteration = 5000;
1018
1145
  const int max_key = keys_iteration * 4 + 10;
@@ -1020,6 +1147,11 @@ TEST_P(BackupableDBTestWithParam, OnlineIntegrationTest) {
1020
1147
  // delete old data
1021
1148
  DestroyDB(dbname_, options_);
1022
1149
 
1150
+ // TODO: Implement & test db_paths support in backup (not supported in
1151
+ // restore)
1152
+ // options_.db_paths.emplace_back(dbname_, 500 * 1024);
1153
+ // options_.db_paths.emplace_back(dbname_ + "_2", 1024 * 1024 * 1024);
1154
+
1023
1155
  OpenDBAndBackupEngine(true);
1024
1156
  // write some data, backup, repeat
1025
1157
  for (int i = 0; i < 5; ++i) {
@@ -1073,41 +1205,40 @@ TEST_P(BackupableDBTestWithParam, OnlineIntegrationTest) {
1073
1205
 
1074
1206
  CloseBackupEngine();
1075
1207
  }
1208
+ #endif // !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
1076
1209
 
1077
- INSTANTIATE_TEST_CASE_P(BackupableDBTestWithParam, BackupableDBTestWithParam,
1210
+ INSTANTIATE_TEST_CASE_P(BackupEngineTestWithParam, BackupEngineTestWithParam,
1078
1211
  ::testing::Bool());
1079
1212
 
1080
1213
  // this will make sure that backup does not copy the same file twice
1081
- TEST_F(BackupableDBTest, NoDoubleCopy_And_AutoGC) {
1214
+ TEST_F(BackupEngineTest, NoDoubleCopy_And_AutoGC) {
1082
1215
  OpenDBAndBackupEngine(true, true);
1083
1216
 
1084
1217
  // should write 5 DB files + one meta file
1085
- test_backup_env_->SetLimitWrittenFiles(7);
1086
- test_backup_env_->ClearWrittenFiles();
1087
- test_db_env_->SetLimitWrittenFiles(0);
1088
- dummy_db_->live_files_ = {"/00010.sst", "/00011.sst", "/CURRENT",
1089
- "/MANIFEST-01"};
1090
- dummy_db_->wal_files_ = {{"/00011.log", true}, {"/00012.log", false}};
1091
- test_db_env_->SetFilenamesForMockedAttrs(dummy_db_->live_files_);
1218
+ test_backup_fs_->SetLimitWrittenFiles(7);
1219
+ test_backup_fs_->ClearWrittenFiles();
1220
+ test_db_fs_->SetLimitWrittenFiles(0);
1221
+ dummy_db_->live_files_ = {"00010.sst", "00011.sst", "CURRENT", "MANIFEST-01",
1222
+ "00011.log"};
1223
+ test_db_fs_->SetFilenamesForMockedAttrs(dummy_db_->live_files_);
1092
1224
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), false));
1093
1225
  std::vector<std::string> should_have_written = {
1094
1226
  "/shared/.00010.sst.tmp", "/shared/.00011.sst.tmp", "/private/1/CURRENT",
1095
1227
  "/private/1/MANIFEST-01", "/private/1/00011.log", "/meta/.1.tmp"};
1096
1228
  AppendPath(backupdir_, should_have_written);
1097
- test_backup_env_->AssertWrittenFiles(should_have_written);
1229
+ test_backup_fs_->AssertWrittenFiles(should_have_written);
1098
1230
 
1099
1231
  char db_number = '1';
1100
1232
 
1101
1233
  for (std::string other_sst : {"00015.sst", "00017.sst", "00019.sst"}) {
1102
1234
  // should write 4 new DB files + one meta file
1103
1235
  // should not write/copy 00010.sst, since it's already there!
1104
- test_backup_env_->SetLimitWrittenFiles(6);
1105
- test_backup_env_->ClearWrittenFiles();
1236
+ test_backup_fs_->SetLimitWrittenFiles(6);
1237
+ test_backup_fs_->ClearWrittenFiles();
1106
1238
 
1107
- dummy_db_->live_files_ = {"/00010.sst", "/" + other_sst, "/CURRENT",
1108
- "/MANIFEST-01"};
1109
- dummy_db_->wal_files_ = {{"/00011.log", true}, {"/00012.log", false}};
1110
- test_db_env_->SetFilenamesForMockedAttrs(dummy_db_->live_files_);
1239
+ dummy_db_->live_files_ = {"00010.sst", other_sst, "CURRENT", "MANIFEST-01",
1240
+ "00011.log"};
1241
+ test_db_fs_->SetFilenamesForMockedAttrs(dummy_db_->live_files_);
1111
1242
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), false));
1112
1243
  // should not open 00010.sst - it's already there
1113
1244
 
@@ -1118,7 +1249,7 @@ TEST_F(BackupableDBTest, NoDoubleCopy_And_AutoGC) {
1118
1249
  private_dir + "/MANIFEST-01", private_dir + "/00011.log",
1119
1250
  std::string("/meta/.") + db_number + ".tmp"};
1120
1251
  AppendPath(backupdir_, should_have_written);
1121
- test_backup_env_->AssertWrittenFiles(should_have_written);
1252
+ test_backup_fs_->AssertWrittenFiles(should_have_written);
1122
1253
  }
1123
1254
 
1124
1255
  ASSERT_OK(backup_engine_->DeleteBackup(1));
@@ -1185,7 +1316,7 @@ TEST_F(BackupableDBTest, NoDoubleCopy_And_AutoGC) {
1185
1316
  // fine
1186
1317
  // 3. Corrupted checksum value - if the checksum is not a valid uint32_t,
1187
1318
  // db open should fail, otherwise, it aborts during the restore process.
1188
- TEST_F(BackupableDBTest, CorruptionsTest) {
1319
+ TEST_F(BackupEngineTest, CorruptionsTest) {
1189
1320
  const int keys_iteration = 5000;
1190
1321
  Random rnd(6);
1191
1322
  Status s;
@@ -1200,11 +1331,11 @@ TEST_F(BackupableDBTest, CorruptionsTest) {
1200
1331
  // ---------- case 1. - fail a write -----------
1201
1332
  // try creating backup 6, but fail a write
1202
1333
  FillDB(db_.get(), keys_iteration * 5, keys_iteration * 6);
1203
- test_backup_env_->SetLimitWrittenFiles(2);
1334
+ test_backup_fs_->SetLimitWrittenFiles(2);
1204
1335
  // should fail
1205
1336
  s = backup_engine_->CreateNewBackup(db_.get(), !!(rnd.Next() % 2));
1206
1337
  ASSERT_NOK(s);
1207
- test_backup_env_->SetLimitWrittenFiles(1000000);
1338
+ test_backup_fs_->SetLimitWrittenFiles(1000000);
1208
1339
  // latest backup should have all the keys
1209
1340
  CloseDBAndBackupEngine();
1210
1341
  AssertBackupConsistency(0, 0, keys_iteration * 5, keys_iteration * 6);
@@ -1286,7 +1417,7 @@ TEST_F(BackupableDBTest, CorruptionsTest) {
1286
1417
  }
1287
1418
 
1288
1419
  // Corrupt a file but maintain its size
1289
- TEST_F(BackupableDBTest, CorruptFileMaintainSize) {
1420
+ TEST_F(BackupEngineTest, CorruptFileMaintainSize) {
1290
1421
  const int keys_iteration = 5000;
1291
1422
  OpenDBAndBackupEngine(true);
1292
1423
  // create a backup
@@ -1305,8 +1436,10 @@ TEST_F(BackupableDBTest, CorruptFileMaintainSize) {
1305
1436
  // under normal circumstance, there should be at least one nonempty file
1306
1437
  while (file_size == 0) {
1307
1438
  // get a random file in /private/1
1308
- ASSERT_OK(file_manager_->GetRandomFileInDir(backupdir_ + "/private/1",
1309
- &file_to_corrupt, &file_size));
1439
+ assert(file_manager_
1440
+ ->GetRandomFileInDir(backupdir_ + "/private/1", &file_to_corrupt,
1441
+ &file_size)
1442
+ .ok());
1310
1443
  // corrupt the file by replacing its content by file_size random bytes
1311
1444
  ASSERT_OK(file_manager_->CorruptFile(file_to_corrupt, file_size));
1312
1445
  }
@@ -1351,17 +1484,62 @@ TEST_F(BackupableDBTest, CorruptFileMaintainSize) {
1351
1484
  CloseDBAndBackupEngine();
1352
1485
  }
1353
1486
 
1487
+ // Corrupt a blob file but maintain its size
1488
+ TEST_P(BackupEngineTestWithParam, CorruptBlobFileMaintainSize) {
1489
+ const int keys_iteration = 5000;
1490
+ OpenDBAndBackupEngine(true);
1491
+ // create a backup
1492
+ FillDB(db_.get(), 0, keys_iteration);
1493
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
1494
+ CloseDBAndBackupEngine();
1495
+
1496
+ OpenDBAndBackupEngine();
1497
+ // verify with file size
1498
+ ASSERT_OK(backup_engine_->VerifyBackup(1, false));
1499
+ // verify with file checksum
1500
+ ASSERT_OK(backup_engine_->VerifyBackup(1, true));
1501
+
1502
+ std::string file_to_corrupt;
1503
+ std::vector<FileAttributes> children;
1504
+
1505
+ std::string dir = backupdir_;
1506
+ if (engine_options_->share_files_with_checksum) {
1507
+ dir += "/shared_checksum";
1508
+ } else {
1509
+ dir += "/shared";
1510
+ }
1511
+
1512
+ ASSERT_OK(file_manager_->GetChildrenFileAttributes(dir, &children));
1513
+
1514
+ for (const auto& child : children) {
1515
+ if (EndsWith(child.name, ".blob") && child.size_bytes != 0) {
1516
+ // corrupt the blob files by replacing its content by file_size random
1517
+ // bytes
1518
+ ASSERT_OK(
1519
+ file_manager_->CorruptFile(dir + "/" + child.name, child.size_bytes));
1520
+ }
1521
+ }
1522
+
1523
+ // file sizes match
1524
+ ASSERT_OK(backup_engine_->VerifyBackup(1, false));
1525
+ // file checksums mismatch
1526
+ ASSERT_NOK(backup_engine_->VerifyBackup(1, true));
1527
+ // sanity check, use default second argument
1528
+ ASSERT_OK(backup_engine_->VerifyBackup(1));
1529
+ CloseDBAndBackupEngine();
1530
+ }
1531
+
1354
1532
  // Test if BackupEngine will fail to create new backup if some table has been
1355
1533
  // corrupted and the table file checksum is stored in the DB manifest
1356
- TEST_F(BackupableDBTest, TableFileCorruptedBeforeBackup) {
1534
+ TEST_F(BackupEngineTest, TableFileCorruptedBeforeBackup) {
1357
1535
  const int keys_iteration = 50000;
1358
1536
 
1359
1537
  OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
1360
1538
  kNoShare);
1361
1539
  FillDB(db_.get(), 0, keys_iteration);
1362
- CloseAndReopenDB();
1540
+ CloseAndReopenDB(/*read_only*/ true);
1363
1541
  // corrupt a random table file in the DB directory
1364
- ASSERT_OK(CorruptRandomTableFileInDB());
1542
+ ASSERT_OK(CorruptRandomDataFileInDB(kTableFile));
1365
1543
  // file_checksum_gen_factory is null, and thus table checksum is not
1366
1544
  // verified for creating a new backup; no correction is detected
1367
1545
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
@@ -1375,26 +1553,61 @@ TEST_F(BackupableDBTest, TableFileCorruptedBeforeBackup) {
1375
1553
  OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
1376
1554
  kNoShare);
1377
1555
  FillDB(db_.get(), 0, keys_iteration);
1378
- CloseAndReopenDB();
1556
+ CloseAndReopenDB(/*read_only*/ true);
1379
1557
  // corrupt a random table file in the DB directory
1380
- ASSERT_OK(CorruptRandomTableFileInDB());
1558
+ ASSERT_OK(CorruptRandomDataFileInDB(kTableFile));
1381
1559
  // table file checksum is enabled so we should be able to detect any
1382
1560
  // corruption
1383
1561
  ASSERT_NOK(backup_engine_->CreateNewBackup(db_.get()));
1384
1562
  CloseDBAndBackupEngine();
1385
1563
  }
1386
1564
 
1565
+ // Test if BackupEngine will fail to create new backup if some blob files has
1566
+ // been corrupted and the blob file checksum is stored in the DB manifest
1567
+ TEST_F(BackupEngineTest, BlobFileCorruptedBeforeBackup) {
1568
+ const int keys_iteration = 50000;
1569
+
1570
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
1571
+ kNoShare);
1572
+ FillDB(db_.get(), 0, keys_iteration);
1573
+ CloseAndReopenDB(/*read_only*/ true);
1574
+ // corrupt a random blob file in the DB directory
1575
+ ASSERT_OK(CorruptRandomDataFileInDB(kBlobFile));
1576
+ // file_checksum_gen_factory is null, and thus blob checksum is not
1577
+ // verified for creating a new backup; no correction is detected
1578
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1579
+ CloseDBAndBackupEngine();
1580
+
1581
+ // delete old files in db
1582
+ ASSERT_OK(DestroyDB(dbname_, options_));
1583
+
1584
+ // Enable file checksum in DB manifest
1585
+ options_.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
1586
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
1587
+ kNoShare);
1588
+ FillDB(db_.get(), 0, keys_iteration);
1589
+ CloseAndReopenDB(/*read_only*/ true);
1590
+ // corrupt a random blob file in the DB directory
1591
+ ASSERT_OK(CorruptRandomDataFileInDB(kBlobFile));
1592
+
1593
+ // file checksum is enabled so we should be able to detect any
1594
+ // corruption
1595
+ ASSERT_NOK(backup_engine_->CreateNewBackup(db_.get()));
1596
+ CloseDBAndBackupEngine();
1597
+ }
1598
+
1599
+ #if !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
1387
1600
  // Test if BackupEngine will fail to create new backup if some table has been
1388
1601
  // corrupted and the table file checksum is stored in the DB manifest for the
1389
1602
  // case when backup table files will be stored in a shared directory
1390
- TEST_P(BackupableDBTestWithParam, TableFileCorruptedBeforeBackup) {
1603
+ TEST_P(BackupEngineTestWithParam, TableFileCorruptedBeforeBackup) {
1391
1604
  const int keys_iteration = 50000;
1392
1605
 
1393
1606
  OpenDBAndBackupEngine(true /* destroy_old_data */);
1394
1607
  FillDB(db_.get(), 0, keys_iteration);
1395
- CloseAndReopenDB();
1608
+ CloseAndReopenDB(/*read_only*/ true);
1396
1609
  // corrupt a random table file in the DB directory
1397
- ASSERT_OK(CorruptRandomTableFileInDB());
1610
+ ASSERT_OK(CorruptRandomDataFileInDB(kTableFile));
1398
1611
  // cannot detect corruption since DB manifest has no table checksums
1399
1612
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1400
1613
  CloseDBAndBackupEngine();
@@ -1406,18 +1619,47 @@ TEST_P(BackupableDBTestWithParam, TableFileCorruptedBeforeBackup) {
1406
1619
  options_.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
1407
1620
  OpenDBAndBackupEngine(true /* destroy_old_data */);
1408
1621
  FillDB(db_.get(), 0, keys_iteration);
1409
- CloseAndReopenDB();
1622
+ CloseAndReopenDB(/*read_only*/ true);
1410
1623
  // corrupt a random table file in the DB directory
1411
- ASSERT_OK(CorruptRandomTableFileInDB());
1624
+ ASSERT_OK(CorruptRandomDataFileInDB(kTableFile));
1625
+ // corruption is detected
1626
+ ASSERT_NOK(backup_engine_->CreateNewBackup(db_.get()));
1627
+ CloseDBAndBackupEngine();
1628
+ }
1629
+
1630
+ // Test if BackupEngine will fail to create new backup if some blob files have
1631
+ // been corrupted and the blob file checksum is stored in the DB manifest for
1632
+ // the case when backup blob files will be stored in a shared directory
1633
+ TEST_P(BackupEngineTestWithParam, BlobFileCorruptedBeforeBackup) {
1634
+ const int keys_iteration = 50000;
1635
+ OpenDBAndBackupEngine(true /* destroy_old_data */);
1636
+ FillDB(db_.get(), 0, keys_iteration);
1637
+ CloseAndReopenDB(/*read_only*/ true);
1638
+ // corrupt a random blob file in the DB directory
1639
+ ASSERT_OK(CorruptRandomDataFileInDB(kBlobFile));
1640
+ // cannot detect corruption since DB manifest has no blob file checksums
1641
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1642
+ CloseDBAndBackupEngine();
1643
+
1644
+ // delete old files in db
1645
+ ASSERT_OK(DestroyDB(dbname_, options_));
1646
+
1647
+ // Enable blob file checksums in DB manifest
1648
+ options_.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
1649
+ OpenDBAndBackupEngine(true /* destroy_old_data */);
1650
+ FillDB(db_.get(), 0, keys_iteration);
1651
+ CloseAndReopenDB(/*read_only*/ true);
1652
+ // corrupt a random blob file in the DB directory
1653
+ ASSERT_OK(CorruptRandomDataFileInDB(kBlobFile));
1412
1654
  // corruption is detected
1413
1655
  ASSERT_NOK(backup_engine_->CreateNewBackup(db_.get()));
1414
1656
  CloseDBAndBackupEngine();
1415
1657
  }
1658
+ #endif // !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
1416
1659
 
1417
- TEST_F(BackupableDBTest, TableFileWithoutDbChecksumCorruptedDuringBackup) {
1660
+ TEST_F(BackupEngineTest, TableFileWithoutDbChecksumCorruptedDuringBackup) {
1418
1661
  const int keys_iteration = 50000;
1419
- backupable_options_->share_files_with_checksum_naming =
1420
- kLegacyCrc32cAndFileSize;
1662
+ engine_options_->share_files_with_checksum_naming = kLegacyCrc32cAndFileSize;
1421
1663
  // When share_files_with_checksum is on, we calculate checksums of table
1422
1664
  // files before and after copying. So we can test whether a corruption has
1423
1665
  // happened during the file is copied to backup directory.
@@ -1455,7 +1697,7 @@ TEST_F(BackupableDBTest, TableFileWithoutDbChecksumCorruptedDuringBackup) {
1455
1697
  ASSERT_OK(DestroyDB(dbname_, options_));
1456
1698
  }
1457
1699
 
1458
- TEST_F(BackupableDBTest, TableFileWithDbChecksumCorruptedDuringBackup) {
1700
+ TEST_F(BackupEngineTest, TableFileWithDbChecksumCorruptedDuringBackup) {
1459
1701
  const int keys_iteration = 50000;
1460
1702
  options_.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
1461
1703
  for (auto& sopt : kAllShareOptions) {
@@ -1495,7 +1737,7 @@ TEST_F(BackupableDBTest, TableFileWithDbChecksumCorruptedDuringBackup) {
1495
1737
  }
1496
1738
  }
1497
1739
 
1498
- TEST_F(BackupableDBTest, InterruptCreationTest) {
1740
+ TEST_F(BackupEngineTest, InterruptCreationTest) {
1499
1741
  // Interrupt backup creation by failing new writes and failing cleanup of the
1500
1742
  // partial state. Then verify a subsequent backup can still succeed.
1501
1743
  const int keys_iteration = 5000;
@@ -1503,8 +1745,8 @@ TEST_F(BackupableDBTest, InterruptCreationTest) {
1503
1745
 
1504
1746
  OpenDBAndBackupEngine(true /* destroy_old_data */);
1505
1747
  FillDB(db_.get(), 0, keys_iteration);
1506
- test_backup_env_->SetLimitWrittenFiles(2);
1507
- test_backup_env_->SetDeleteFileFailure(true);
1748
+ test_backup_fs_->SetLimitWrittenFiles(2);
1749
+ test_backup_fs_->SetDeleteFileFailure(true);
1508
1750
  // should fail creation
1509
1751
  ASSERT_NOK(backup_engine_->CreateNewBackup(db_.get(), !!(rnd.Next() % 2)));
1510
1752
  CloseDBAndBackupEngine();
@@ -1512,15 +1754,15 @@ TEST_F(BackupableDBTest, InterruptCreationTest) {
1512
1754
  ASSERT_OK(backup_chroot_env_->FileExists(backupdir_ + "/private/1/"));
1513
1755
 
1514
1756
  OpenDBAndBackupEngine(false /* destroy_old_data */);
1515
- test_backup_env_->SetLimitWrittenFiles(1000000);
1516
- test_backup_env_->SetDeleteFileFailure(false);
1757
+ test_backup_fs_->SetLimitWrittenFiles(1000000);
1758
+ test_backup_fs_->SetDeleteFileFailure(false);
1517
1759
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), !!(rnd.Next() % 2)));
1518
1760
  // latest backup should have all the keys
1519
1761
  CloseDBAndBackupEngine();
1520
1762
  AssertBackupConsistency(0, 0, keys_iteration);
1521
1763
  }
1522
1764
 
1523
- TEST_F(BackupableDBTest, FlushCompactDuringBackupCheckpoint) {
1765
+ TEST_F(BackupEngineTest, FlushCompactDuringBackupCheckpoint) {
1524
1766
  const int keys_iteration = 5000;
1525
1767
  options_.file_checksum_gen_factory = GetFileChecksumGenCrc32cFactory();
1526
1768
  for (const auto& sopt : kAllShareOptions) {
@@ -1529,13 +1771,13 @@ TEST_F(BackupableDBTest, FlushCompactDuringBackupCheckpoint) {
1529
1771
  // That FillDB leaves a mix of flushed and unflushed data
1530
1772
  SyncPoint::GetInstance()->LoadDependency(
1531
1773
  {{"CheckpointImpl::CreateCustomCheckpoint:AfterGetLive1",
1532
- "BackupableDBTest::FlushCompactDuringBackupCheckpoint:Before"},
1533
- {"BackupableDBTest::FlushCompactDuringBackupCheckpoint:After",
1774
+ "BackupEngineTest::FlushCompactDuringBackupCheckpoint:Before"},
1775
+ {"BackupEngineTest::FlushCompactDuringBackupCheckpoint:After",
1534
1776
  "CheckpointImpl::CreateCustomCheckpoint:AfterGetLive2"}});
1535
1777
  SyncPoint::GetInstance()->EnableProcessing();
1536
1778
  ROCKSDB_NAMESPACE::port::Thread flush_thread{[this]() {
1537
1779
  TEST_SYNC_POINT(
1538
- "BackupableDBTest::FlushCompactDuringBackupCheckpoint:Before");
1780
+ "BackupEngineTest::FlushCompactDuringBackupCheckpoint:Before");
1539
1781
  FillDB(db_.get(), keys_iteration, 2 * keys_iteration);
1540
1782
  ASSERT_OK(db_->Flush(FlushOptions()));
1541
1783
  DBImpl* dbi = static_cast<DBImpl*>(db_.get());
@@ -1543,7 +1785,7 @@ TEST_F(BackupableDBTest, FlushCompactDuringBackupCheckpoint) {
1543
1785
  ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
1544
1786
  ASSERT_OK(dbi->TEST_WaitForCompact());
1545
1787
  TEST_SYNC_POINT(
1546
- "BackupableDBTest::FlushCompactDuringBackupCheckpoint:After");
1788
+ "BackupEngineTest::FlushCompactDuringBackupCheckpoint:After");
1547
1789
  }};
1548
1790
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1549
1791
  flush_thread.join();
@@ -1554,7 +1796,7 @@ TEST_F(BackupableDBTest, FlushCompactDuringBackupCheckpoint) {
1554
1796
  if (sopt == kShareWithChecksum) {
1555
1797
  // Ensure we actually got DB manifest checksums by inspecting
1556
1798
  // shared_checksum file names for hex checksum component
1557
- std::regex expected("[^_]+_[0-9A-F]{8}_[^_]+.sst");
1799
+ TestRegex expected("[^_]+_[0-9A-F]{8}_[^_]+.sst");
1558
1800
  std::vector<FileAttributes> children;
1559
1801
  const std::string dir = backupdir_ + "/shared_checksum";
1560
1802
  ASSERT_OK(file_manager_->GetChildrenFileAttributes(dir, &children));
@@ -1562,8 +1804,7 @@ TEST_F(BackupableDBTest, FlushCompactDuringBackupCheckpoint) {
1562
1804
  if (child.size_bytes == 0) {
1563
1805
  continue;
1564
1806
  }
1565
- const std::string match("match");
1566
- EXPECT_EQ(match, std::regex_replace(child.name, expected, match));
1807
+ EXPECT_MATCHES_REGEX(child.name, expected);
1567
1808
  }
1568
1809
  }
1569
1810
  */
@@ -1581,7 +1822,7 @@ inline std::string OptionsPath(std::string ret, int backupID) {
1581
1822
  // Backup the LATEST options file to
1582
1823
  // "<backup_dir>/private/<backup_id>/OPTIONS<number>"
1583
1824
 
1584
- TEST_F(BackupableDBTest, BackupOptions) {
1825
+ TEST_F(BackupEngineTest, BackupOptions) {
1585
1826
  OpenDBAndBackupEngine(true);
1586
1827
  for (int i = 1; i < 5; i++) {
1587
1828
  std::string name;
@@ -1606,17 +1847,17 @@ TEST_F(BackupableDBTest, BackupOptions) {
1606
1847
  CloseDBAndBackupEngine();
1607
1848
  }
1608
1849
 
1609
- TEST_F(BackupableDBTest, SetOptionsBackupRaceCondition) {
1850
+ TEST_F(BackupEngineTest, SetOptionsBackupRaceCondition) {
1610
1851
  OpenDBAndBackupEngine(true);
1611
1852
  SyncPoint::GetInstance()->LoadDependency(
1612
1853
  {{"CheckpointImpl::CreateCheckpoint:SavedLiveFiles1",
1613
- "BackupableDBTest::SetOptionsBackupRaceCondition:BeforeSetOptions"},
1614
- {"BackupableDBTest::SetOptionsBackupRaceCondition:AfterSetOptions",
1854
+ "BackupEngineTest::SetOptionsBackupRaceCondition:BeforeSetOptions"},
1855
+ {"BackupEngineTest::SetOptionsBackupRaceCondition:AfterSetOptions",
1615
1856
  "CheckpointImpl::CreateCheckpoint:SavedLiveFiles2"}});
1616
1857
  SyncPoint::GetInstance()->EnableProcessing();
1617
1858
  ROCKSDB_NAMESPACE::port::Thread setoptions_thread{[this]() {
1618
1859
  TEST_SYNC_POINT(
1619
- "BackupableDBTest::SetOptionsBackupRaceCondition:BeforeSetOptions");
1860
+ "BackupEngineTest::SetOptionsBackupRaceCondition:BeforeSetOptions");
1620
1861
  DBImpl* dbi = static_cast<DBImpl*>(db_.get());
1621
1862
  // Change arbitrary option to trigger OPTIONS file deletion
1622
1863
  ASSERT_OK(dbi->SetOptions(dbi->DefaultColumnFamily(),
@@ -1626,7 +1867,7 @@ TEST_F(BackupableDBTest, SetOptionsBackupRaceCondition) {
1626
1867
  ASSERT_OK(dbi->SetOptions(dbi->DefaultColumnFamily(),
1627
1868
  {{"paranoid_file_checks", "false"}}));
1628
1869
  TEST_SYNC_POINT(
1629
- "BackupableDBTest::SetOptionsBackupRaceCondition:AfterSetOptions");
1870
+ "BackupEngineTest::SetOptionsBackupRaceCondition:AfterSetOptions");
1630
1871
  }};
1631
1872
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1632
1873
  setoptions_thread.join();
@@ -1635,7 +1876,7 @@ TEST_F(BackupableDBTest, SetOptionsBackupRaceCondition) {
1635
1876
 
1636
1877
  // This test verifies we don't delete the latest backup when read-only option is
1637
1878
  // set
1638
- TEST_F(BackupableDBTest, NoDeleteWithReadOnly) {
1879
+ TEST_F(BackupEngineTest, NoDeleteWithReadOnly) {
1639
1880
  const int keys_iteration = 5000;
1640
1881
  Random rnd(6);
1641
1882
 
@@ -1646,13 +1887,12 @@ TEST_F(BackupableDBTest, NoDeleteWithReadOnly) {
1646
1887
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), !!(rnd.Next() % 2)));
1647
1888
  }
1648
1889
  CloseDBAndBackupEngine();
1649
- ASSERT_OK(file_manager_->WriteToFile(backupdir_ + "/LATEST_BACKUP", "4"));
1890
+ ASSERT_OK(file_manager_->WriteToFile(latest_backup_, "4"));
1650
1891
 
1651
- backupable_options_->destroy_old_data = false;
1892
+ engine_options_->destroy_old_data = false;
1652
1893
  BackupEngineReadOnly* read_only_backup_engine;
1653
- ASSERT_OK(BackupEngineReadOnly::Open(backup_chroot_env_.get(),
1654
- *backupable_options_,
1655
- &read_only_backup_engine));
1894
+ ASSERT_OK(BackupEngineReadOnly::Open(
1895
+ backup_chroot_env_.get(), *engine_options_, &read_only_backup_engine));
1656
1896
 
1657
1897
  // assert that data from backup 5 is still here (even though LATEST_BACKUP
1658
1898
  // says 4 is latest)
@@ -1667,7 +1907,7 @@ TEST_F(BackupableDBTest, NoDeleteWithReadOnly) {
1667
1907
  delete read_only_backup_engine;
1668
1908
  }
1669
1909
 
1670
- TEST_F(BackupableDBTest, FailOverwritingBackups) {
1910
+ TEST_F(BackupEngineTest, FailOverwritingBackups) {
1671
1911
  options_.write_buffer_size = 1024 * 1024 * 1024; // 1GB
1672
1912
  options_.disable_auto_compactions = true;
1673
1913
 
@@ -1705,7 +1945,7 @@ TEST_F(BackupableDBTest, FailOverwritingBackups) {
1705
1945
  CloseDBAndBackupEngine();
1706
1946
  }
1707
1947
 
1708
- TEST_F(BackupableDBTest, NoShareTableFiles) {
1948
+ TEST_F(BackupEngineTest, NoShareTableFiles) {
1709
1949
  const int keys_iteration = 5000;
1710
1950
  OpenDBAndBackupEngine(true, false, kNoShare);
1711
1951
  for (int i = 0; i < 5; ++i) {
@@ -1721,7 +1961,7 @@ TEST_F(BackupableDBTest, NoShareTableFiles) {
1721
1961
  }
1722
1962
 
1723
1963
  // Verify that you can backup and restore with share_files_with_checksum on
1724
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksums) {
1964
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksums) {
1725
1965
  const int keys_iteration = 5000;
1726
1966
  OpenDBAndBackupEngine(true, false, kShareWithChecksum);
1727
1967
  for (int i = 0; i < 5; ++i) {
@@ -1738,7 +1978,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksums) {
1738
1978
 
1739
1979
  // Verify that you can backup and restore using share_files_with_checksum set to
1740
1980
  // false and then transition this option to true
1741
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsTransition) {
1981
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksumsTransition) {
1742
1982
  const int keys_iteration = 5000;
1743
1983
  // set share_files_with_checksum to false
1744
1984
  OpenDBAndBackupEngine(true, false, kShareNoChecksum);
@@ -1780,8 +2020,8 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsTransition) {
1780
2020
  }
1781
2021
 
1782
2022
  // Verify backup and restore with various naming options, check names
1783
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNaming) {
1784
- ASSERT_TRUE(backupable_options_->share_files_with_checksum_naming ==
2023
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksumsNewNaming) {
2024
+ ASSERT_TRUE(engine_options_->share_files_with_checksum_naming ==
1785
2025
  kNamingDefault);
1786
2026
 
1787
2027
  const int keys_iteration = 5000;
@@ -1790,7 +2030,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNaming) {
1790
2030
  FillDB(db_.get(), 0, keys_iteration);
1791
2031
  CloseDBAndBackupEngine();
1792
2032
 
1793
- static const std::map<ShareFilesNaming, std::string> option_to_expected = {
2033
+ static const std::map<ShareFilesNaming, TestRegex> option_to_expected = {
1794
2034
  {kLegacyCrc32cAndFileSize, "[0-9]+_[0-9]+_[0-9]+[.]sst"},
1795
2035
  // kFlagIncludeFileSize redundant here
1796
2036
  {kLegacyCrc32cAndFileSize | kFlagIncludeFileSize,
@@ -1800,82 +2040,31 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNaming) {
1800
2040
  "[0-9]+_s[0-9A-Z]{20}_[0-9]+[.]sst"},
1801
2041
  };
1802
2042
 
1803
- for (const auto& pair : option_to_expected) {
1804
- // kFlagMatchInterimNaming must not matter on new SST files
1805
- for (const auto option :
1806
- {pair.first, pair.first | kFlagMatchInterimNaming}) {
1807
- CloseAndReopenDB();
1808
- backupable_options_->share_files_with_checksum_naming = option;
1809
- OpenBackupEngine(true /*destroy_old_data*/);
1810
- ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1811
- CloseDBAndBackupEngine();
1812
- AssertBackupConsistency(1, 0, keys_iteration, keys_iteration * 2);
1813
- AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum",
1814
- std::regex(pair.second),
1815
- 1 /* minimum_count */);
1816
- if (std::string::npos != pair.second.find("_[0-9]+[.]sst")) {
1817
- AssertDirectoryFilesSizeIndicators(backupdir_ + "/shared_checksum",
1818
- 1 /* minimum_count */);
1819
- }
1820
- }
1821
- }
1822
- }
1823
-
1824
- // Mimic SST file generated by early internal-only 6.12 release
1825
- // and test various naming options. This test can be removed when
1826
- // the kFlagMatchInterimNaming feature is removed.
1827
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsInterimNaming) {
1828
- const int keys_iteration = 5000;
1829
-
1830
- // Essentially, reinstate old implementaiton of generating a DB
1831
- // session id. This is how we distinguish "interim" SST files from
1832
- // newer ones: from the form of the db session id string.
1833
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
1834
- "DBImpl::SetDbSessionId", [&](void* sid_void_star) {
1835
- std::string* sid = static_cast<std::string*>(sid_void_star);
1836
- *sid = test_db_env_->GenerateUniqueId();
1837
- if (!sid->empty() && sid->back() == '\n') {
1838
- sid->pop_back();
1839
- }
1840
- });
1841
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
1842
-
1843
- OpenDBAndBackupEngine(true, false, kShareWithChecksum);
1844
- FillDB(db_.get(), 0, keys_iteration);
1845
- CloseDBAndBackupEngine();
1846
-
1847
- static const std::map<ShareFilesNaming, std::string> option_to_expected = {
1848
- {kLegacyCrc32cAndFileSize, "[0-9]+_[0-9]+_[0-9]+[.]sst"},
1849
- // kFlagMatchInterimNaming ignored here
1850
- {kLegacyCrc32cAndFileSize | kFlagMatchInterimNaming,
1851
- "[0-9]+_[0-9]+_[0-9]+[.]sst"},
1852
- {kUseDbSessionId, "[0-9]+_s[0-9a-fA-F-]+[.]sst"},
1853
- {kUseDbSessionId | kFlagIncludeFileSize,
1854
- "[0-9]+_s[0-9a-fA-F-]+_[0-9]+[.]sst"},
1855
- {kUseDbSessionId | kFlagMatchInterimNaming, "[0-9]+_[0-9a-fA-F-]+[.]sst"},
1856
- {kUseDbSessionId | kFlagIncludeFileSize | kFlagMatchInterimNaming,
1857
- "[0-9]+_[0-9a-fA-F-]+[.]sst"},
1858
- };
2043
+ const TestRegex blobfile_pattern = "[0-9]+_[0-9]+_[0-9]+[.]blob";
1859
2044
 
1860
2045
  for (const auto& pair : option_to_expected) {
1861
2046
  CloseAndReopenDB();
1862
- backupable_options_->share_files_with_checksum_naming = pair.first;
2047
+ engine_options_->share_files_with_checksum_naming = pair.first;
1863
2048
  OpenBackupEngine(true /*destroy_old_data*/);
1864
2049
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1865
2050
  CloseDBAndBackupEngine();
1866
2051
  AssertBackupConsistency(1, 0, keys_iteration, keys_iteration * 2);
2052
+ AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum", pair.second,
2053
+ ".sst", 1 /* minimum_count */);
2054
+ if (std::string::npos != pair.second.GetPattern().find("_[0-9]+[.]sst")) {
2055
+ AssertDirectoryFilesSizeIndicators(backupdir_ + "/shared_checksum",
2056
+ 1 /* minimum_count */);
2057
+ }
2058
+
1867
2059
  AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum",
1868
- std::regex(pair.second),
2060
+ blobfile_pattern, ".blob",
1869
2061
  1 /* minimum_count */);
1870
2062
  }
1871
-
1872
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
1873
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->ClearAllCallBacks();
1874
2063
  }
1875
2064
 
1876
2065
  // Mimic SST file generated by pre-6.12 releases and verify that
1877
2066
  // old names are always used regardless of naming option.
1878
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsOldFileNaming) {
2067
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksumsOldFileNaming) {
1879
2068
  const int keys_iteration = 5000;
1880
2069
 
1881
2070
  // Pre-6.12 release did not include db id and db session id properties.
@@ -1892,16 +2081,22 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsOldFileNaming) {
1892
2081
  CloseDBAndBackupEngine();
1893
2082
 
1894
2083
  // Old names should always be used on old files
1895
- const std::regex expected("[0-9]+_[0-9]+_[0-9]+[.]sst");
2084
+ const TestRegex sstfile_pattern("[0-9]+_[0-9]+_[0-9]+[.]sst");
2085
+
2086
+ const TestRegex blobfile_pattern = "[0-9]+_[0-9]+_[0-9]+[.]blob";
1896
2087
 
1897
2088
  for (ShareFilesNaming option : {kNamingDefault, kUseDbSessionId}) {
1898
2089
  CloseAndReopenDB();
1899
- backupable_options_->share_files_with_checksum_naming = option;
2090
+ engine_options_->share_files_with_checksum_naming = option;
1900
2091
  OpenBackupEngine(true /*destroy_old_data*/);
1901
2092
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
1902
2093
  CloseDBAndBackupEngine();
1903
2094
  AssertBackupConsistency(1, 0, keys_iteration, keys_iteration * 2);
1904
- AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum", expected,
2095
+ AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum",
2096
+ sstfile_pattern, ".sst",
2097
+ 1 /* minimum_count */);
2098
+ AssertDirectoryFilesMatchRegex(backupdir_ + "/shared_checksum",
2099
+ blobfile_pattern, ".blob",
1905
2100
  1 /* minimum_count */);
1906
2101
  }
1907
2102
 
@@ -1911,7 +2106,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsOldFileNaming) {
1911
2106
 
1912
2107
  // Test how naming options interact with detecting DB corruption
1913
2108
  // between incremental backups
1914
- TEST_F(BackupableDBTest, TableFileCorruptionBeforeIncremental) {
2109
+ TEST_F(BackupEngineTest, TableFileCorruptionBeforeIncremental) {
1915
2110
  const auto share_no_checksum = static_cast<ShareFilesNaming>(0);
1916
2111
 
1917
2112
  for (bool corrupt_before_first_backup : {false, true}) {
@@ -1920,7 +2115,7 @@ TEST_F(BackupableDBTest, TableFileCorruptionBeforeIncremental) {
1920
2115
  auto share =
1921
2116
  option == share_no_checksum ? kShareNoChecksum : kShareWithChecksum;
1922
2117
  if (option != share_no_checksum) {
1923
- backupable_options_->share_files_with_checksum_naming = option;
2118
+ engine_options_->share_files_with_checksum_naming = option;
1924
2119
  }
1925
2120
  OpenDBAndBackupEngine(true, false, share);
1926
2121
  DBImpl* dbi = static_cast<DBImpl*>(db_.get());
@@ -1931,14 +2126,16 @@ TEST_F(BackupableDBTest, TableFileCorruptionBeforeIncremental) {
1931
2126
  ASSERT_OK(dbi->Put(WriteOptions(), "y", Random(42).RandomString(500)));
1932
2127
  ASSERT_OK(dbi->Flush(FlushOptions()));
1933
2128
  ASSERT_OK(dbi->TEST_WaitForFlushMemTable());
1934
- CloseDBAndBackupEngine();
2129
+ CloseAndReopenDB(/*read_only*/ true);
1935
2130
 
1936
2131
  std::vector<FileAttributes> table_files;
1937
- ASSERT_OK(GetTableFilesInDB(&table_files));
2132
+ ASSERT_OK(GetDataFilesInDB(kTableFile, &table_files));
1938
2133
  ASSERT_EQ(table_files.size(), 2);
1939
2134
  std::string tf0 = dbname_ + "/" + table_files[0].name;
1940
2135
  std::string tf1 = dbname_ + "/" + table_files[1].name;
1941
2136
 
2137
+ CloseDBAndBackupEngine();
2138
+
1942
2139
  if (corrupt_before_first_backup) {
1943
2140
  // This corrupts a data block, which does not cause DB open
1944
2141
  // failure, only failure on accessing the block.
@@ -2017,15 +2214,17 @@ TEST_F(BackupableDBTest, TableFileCorruptionBeforeIncremental) {
2017
2214
 
2018
2215
  // Test how naming options interact with detecting file size corruption
2019
2216
  // between incremental backups
2020
- TEST_F(BackupableDBTest, FileSizeForIncremental) {
2217
+ TEST_F(BackupEngineTest, FileSizeForIncremental) {
2021
2218
  const auto share_no_checksum = static_cast<ShareFilesNaming>(0);
2219
+ // TODO: enable blob files once Integrated BlobDB supports DB session id.
2220
+ options_.enable_blob_files = false;
2022
2221
 
2023
2222
  for (ShareFilesNaming option : {share_no_checksum, kLegacyCrc32cAndFileSize,
2024
2223
  kNamingDefault, kUseDbSessionId}) {
2025
2224
  auto share =
2026
2225
  option == share_no_checksum ? kShareNoChecksum : kShareWithChecksum;
2027
2226
  if (option != share_no_checksum) {
2028
- backupable_options_->share_files_with_checksum_naming = option;
2227
+ engine_options_->share_files_with_checksum_naming = option;
2029
2228
  }
2030
2229
  OpenDBAndBackupEngine(true, false, share);
2031
2230
 
@@ -2043,7 +2242,7 @@ TEST_F(BackupableDBTest, FileSizeForIncremental) {
2043
2242
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true /*flush*/));
2044
2243
  CloseDBAndBackupEngine();
2045
2244
 
2046
- // Corrupt backup SST
2245
+ // Corrupt backup SST file
2047
2246
  ASSERT_OK(file_manager_->GetChildrenFileAttributes(shared_dir, &children));
2048
2247
  ASSERT_EQ(children.size(), 1U); // one sst
2049
2248
  for (const auto& child : children) {
@@ -2102,10 +2301,10 @@ TEST_F(BackupableDBTest, FileSizeForIncremental) {
2102
2301
  OpenDBAndBackupEngine(false, false, share);
2103
2302
  ASSERT_OK(db_->Put(WriteOptions(), "y", Random(42).RandomString(500)));
2104
2303
 
2105
- // Count backup SSTs
2304
+ // Count backup SSTs files.
2106
2305
  children.clear();
2107
2306
  ASSERT_OK(file_manager_->GetChildrenFileAttributes(shared_dir, &children));
2108
- ASSERT_EQ(children.size(), 2U); // two sst
2307
+ ASSERT_EQ(children.size(), 2U); // two sst files
2109
2308
 
2110
2309
  // Try create backup 3
2111
2310
  s = backup_engine_->CreateNewBackup(db_.get(), true /*flush*/);
@@ -2118,12 +2317,12 @@ TEST_F(BackupableDBTest, FileSizeForIncremental) {
2118
2317
  // Acceptable to call it corruption if size is not in name and
2119
2318
  // db session id collision is practically impossible.
2120
2319
  EXPECT_TRUE(s.IsCorruption());
2121
- EXPECT_EQ(children.size(), 2U); // no SST added
2320
+ EXPECT_EQ(children.size(), 2U); // no SST file added
2122
2321
  } else if (option == share_no_checksum) {
2123
2322
  // Good to call it corruption if both backups cannot be
2124
2323
  // accommodated.
2125
2324
  EXPECT_TRUE(s.IsCorruption());
2126
- EXPECT_EQ(children.size(), 2U); // no SST added
2325
+ EXPECT_EQ(children.size(), 2U); // no SST file added
2127
2326
  } else {
2128
2327
  // Since opening a DB seems sufficient for detecting size corruption
2129
2328
  // on the DB side, this should be a good thing, ...
@@ -2141,12 +2340,12 @@ TEST_F(BackupableDBTest, FileSizeForIncremental) {
2141
2340
  // Verify backup and restore with share_files_with_checksum off and then
2142
2341
  // transition this option to on and share_files_with_checksum_naming to be
2143
2342
  // based on kUseDbSessionId
2144
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2343
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2145
2344
  const int keys_iteration = 5000;
2146
2345
  // We may set share_files_with_checksum_naming to kLegacyCrc32cAndFileSize
2147
2346
  // here but even if we don't, it should have no effect when
2148
2347
  // share_files_with_checksum is false
2149
- ASSERT_TRUE(backupable_options_->share_files_with_checksum_naming ==
2348
+ ASSERT_TRUE(engine_options_->share_files_with_checksum_naming ==
2150
2349
  kNamingDefault);
2151
2350
  // set share_files_with_checksum to false
2152
2351
  OpenDBAndBackupEngine(true, false, kShareNoChecksum);
@@ -2164,7 +2363,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2164
2363
 
2165
2364
  // set share_files_with_checksum to true and do some more backups
2166
2365
  // and use session id in the name of SST file backup
2167
- ASSERT_TRUE(backupable_options_->share_files_with_checksum_naming ==
2366
+ ASSERT_TRUE(engine_options_->share_files_with_checksum_naming ==
2168
2367
  kNamingDefault);
2169
2368
  OpenDBAndBackupEngine(false /* destroy_old_data */, false,
2170
2369
  kShareWithChecksum);
@@ -2186,7 +2385,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2186
2385
  // For an extra challenge, make sure that GarbageCollect / DeleteBackup
2187
2386
  // is OK even if we open without share_table_files but with
2188
2387
  // share_files_with_checksum_naming based on kUseDbSessionId
2189
- ASSERT_TRUE(backupable_options_->share_files_with_checksum_naming ==
2388
+ ASSERT_TRUE(engine_options_->share_files_with_checksum_naming ==
2190
2389
  kNamingDefault);
2191
2390
  OpenDBAndBackupEngine(false /* destroy_old_data */, false, kNoShare);
2192
2391
  ASSERT_OK(backup_engine_->DeleteBackup(1));
@@ -2199,8 +2398,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2199
2398
  // Use checksum and file size for backup table file names and open without
2200
2399
  // share_table_files
2201
2400
  // Again, make sure that GarbageCollect / DeleteBackup is OK
2202
- backupable_options_->share_files_with_checksum_naming =
2203
- kLegacyCrc32cAndFileSize;
2401
+ engine_options_->share_files_with_checksum_naming = kLegacyCrc32cAndFileSize;
2204
2402
  OpenDBAndBackupEngine(false /* destroy_old_data */, false, kNoShare);
2205
2403
  ASSERT_OK(backup_engine_->DeleteBackup(2));
2206
2404
  ASSERT_OK(backup_engine_->GarbageCollect());
@@ -2215,9 +2413,8 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingTransition) {
2215
2413
 
2216
2414
  // Verify backup and restore with share_files_with_checksum on and transition
2217
2415
  // from kLegacyCrc32cAndFileSize to kUseDbSessionId
2218
- TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingUpgrade) {
2219
- backupable_options_->share_files_with_checksum_naming =
2220
- kLegacyCrc32cAndFileSize;
2416
+ TEST_F(BackupEngineTest, ShareTableFilesWithChecksumsNewNamingUpgrade) {
2417
+ engine_options_->share_files_with_checksum_naming = kLegacyCrc32cAndFileSize;
2221
2418
  const int keys_iteration = 5000;
2222
2419
  // set share_files_with_checksum to true
2223
2420
  OpenDBAndBackupEngine(true, false, kShareWithChecksum);
@@ -2233,7 +2430,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingUpgrade) {
2233
2430
  keys_iteration * (j + 1));
2234
2431
  }
2235
2432
 
2236
- backupable_options_->share_files_with_checksum_naming = kUseDbSessionId;
2433
+ engine_options_->share_files_with_checksum_naming = kUseDbSessionId;
2237
2434
  OpenDBAndBackupEngine(false /* destroy_old_data */, false,
2238
2435
  kShareWithChecksum);
2239
2436
  FillDB(db_.get(), keys_iteration * j, keys_iteration * (j + 1));
@@ -2264,8 +2461,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingUpgrade) {
2264
2461
  // Use checksum and file size for backup table file names and open without
2265
2462
  // share_table_files
2266
2463
  // Again, make sure that GarbageCollect / DeleteBackup is OK
2267
- backupable_options_->share_files_with_checksum_naming =
2268
- kLegacyCrc32cAndFileSize;
2464
+ engine_options_->share_files_with_checksum_naming = kLegacyCrc32cAndFileSize;
2269
2465
  OpenDBAndBackupEngine(false /* destroy_old_data */, false, kNoShare);
2270
2466
  ASSERT_OK(backup_engine_->DeleteBackup(2));
2271
2467
  ASSERT_OK(backup_engine_->GarbageCollect());
@@ -2280,7 +2476,7 @@ TEST_F(BackupableDBTest, ShareTableFilesWithChecksumsNewNamingUpgrade) {
2280
2476
 
2281
2477
  // This test simulates cleaning up after aborted or incomplete creation
2282
2478
  // of a new backup.
2283
- TEST_F(BackupableDBTest, DeleteTmpFiles) {
2479
+ TEST_F(BackupEngineTest, DeleteTmpFiles) {
2284
2480
  for (int cleanup_fn : {1, 2, 3, 4}) {
2285
2481
  for (ShareOption shared_option : kAllShareOptions) {
2286
2482
  OpenDBAndBackupEngine(false /* destroy_old_data */, false /* dummy */,
@@ -2358,8 +2554,8 @@ TEST_F(BackupableDBTest, DeleteTmpFiles) {
2358
2554
  }
2359
2555
  }
2360
2556
 
2361
- TEST_F(BackupableDBTest, KeepLogFiles) {
2362
- backupable_options_->backup_log_files = false;
2557
+ TEST_F(BackupEngineTest, KeepLogFiles) {
2558
+ engine_options_->backup_log_files = false;
2363
2559
  // basically infinite
2364
2560
  options_.WAL_ttl_seconds = 24 * 60 * 60;
2365
2561
  OpenDBAndBackupEngine(true);
@@ -2375,20 +2571,21 @@ TEST_F(BackupableDBTest, KeepLogFiles) {
2375
2571
  AssertBackupConsistency(0, 0, 500, 600, true);
2376
2572
  }
2377
2573
 
2378
- class BackupableDBRateLimitingTestWithParam
2379
- : public BackupableDBTest,
2574
+ #if !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
2575
+ class BackupEngineRateLimitingTestWithParam
2576
+ : public BackupEngineTest,
2380
2577
  public testing::WithParamInterface<
2381
2578
  std::tuple<bool /* make throttle */,
2382
2579
  int /* 0 = single threaded, 1 = multi threaded*/,
2383
2580
  std::pair<uint64_t, uint64_t> /* limits */>> {
2384
2581
  public:
2385
- BackupableDBRateLimitingTestWithParam() {}
2582
+ BackupEngineRateLimitingTestWithParam() {}
2386
2583
  };
2387
2584
 
2388
2585
  uint64_t const MB = 1024 * 1024;
2389
2586
 
2390
2587
  INSTANTIATE_TEST_CASE_P(
2391
- RateLimiting, BackupableDBRateLimitingTestWithParam,
2588
+ RateLimiting, BackupEngineRateLimitingTestWithParam,
2392
2589
  ::testing::Values(std::make_tuple(false, 0, std::make_pair(1 * MB, 5 * MB)),
2393
2590
  std::make_tuple(false, 0, std::make_pair(2 * MB, 3 * MB)),
2394
2591
  std::make_tuple(false, 1, std::make_pair(1 * MB, 5 * MB)),
@@ -2399,7 +2596,7 @@ INSTANTIATE_TEST_CASE_P(
2399
2596
  std::make_tuple(true, 1,
2400
2597
  std::make_pair(2 * MB, 3 * MB))));
2401
2598
 
2402
- TEST_P(BackupableDBRateLimitingTestWithParam, RateLimiting) {
2599
+ TEST_P(BackupEngineRateLimitingTestWithParam, RateLimiting) {
2403
2600
  size_t const kMicrosPerSec = 1000 * 1000LL;
2404
2601
 
2405
2602
  std::shared_ptr<RateLimiter> backupThrottler(NewGenericRateLimiter(1));
@@ -2407,8 +2604,8 @@ TEST_P(BackupableDBRateLimitingTestWithParam, RateLimiting) {
2407
2604
 
2408
2605
  bool makeThrottler = std::get<0>(GetParam());
2409
2606
  if (makeThrottler) {
2410
- backupable_options_->backup_rate_limiter = backupThrottler;
2411
- backupable_options_->restore_rate_limiter = restoreThrottler;
2607
+ engine_options_->backup_rate_limiter = backupThrottler;
2608
+ engine_options_->restore_rate_limiter = restoreThrottler;
2412
2609
  }
2413
2610
 
2414
2611
  // iter 0 -- single threaded
@@ -2422,10 +2619,10 @@ TEST_P(BackupableDBRateLimitingTestWithParam, RateLimiting) {
2422
2619
  backupThrottler->SetBytesPerSecond(limit.first);
2423
2620
  restoreThrottler->SetBytesPerSecond(limit.second);
2424
2621
  } else {
2425
- backupable_options_->backup_rate_limit = limit.first;
2426
- backupable_options_->restore_rate_limit = limit.second;
2622
+ engine_options_->backup_rate_limit = limit.first;
2623
+ engine_options_->restore_rate_limit = limit.second;
2427
2624
  }
2428
- backupable_options_->max_background_operations = (iter == 0) ? 1 : 10;
2625
+ engine_options_->max_background_operations = (iter == 0) ? 1 : 10;
2429
2626
  options_.compression = kNoCompression;
2430
2627
  OpenDBAndBackupEngine(true);
2431
2628
  size_t bytes_written = FillDB(db_.get(), 0, 100000);
@@ -2450,70 +2647,428 @@ TEST_P(BackupableDBRateLimitingTestWithParam, RateLimiting) {
2450
2647
  AssertBackupConsistency(0, 0, 100000, 100010);
2451
2648
  }
2452
2649
 
2453
- TEST_F(BackupableDBTest, ReadOnlyBackupEngine) {
2454
- DestroyDB(dbname_, options_);
2455
- OpenDBAndBackupEngine(true);
2456
- FillDB(db_.get(), 0, 100);
2457
- ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2458
- FillDB(db_.get(), 100, 200);
2459
- ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2460
- CloseDBAndBackupEngine();
2461
- DestroyDB(dbname_, options_);
2650
+ TEST_P(BackupEngineRateLimitingTestWithParam, RateLimitingVerifyBackup) {
2651
+ const std::size_t kMicrosPerSec = 1000 * 1000LL;
2652
+ std::shared_ptr<RateLimiter> backupThrottler(NewGenericRateLimiter(
2653
+ 1, 100 * 1000 /* refill_period_us */, 10 /* fairness */,
2654
+ RateLimiter::Mode::kAllIo /* mode */));
2462
2655
 
2463
- backupable_options_->destroy_old_data = false;
2464
- test_backup_env_->ClearWrittenFiles();
2465
- test_backup_env_->SetLimitDeleteFiles(0);
2466
- BackupEngineReadOnly* read_only_backup_engine;
2467
- ASSERT_OK(BackupEngineReadOnly::Open(
2468
- db_chroot_env_.get(), *backupable_options_, &read_only_backup_engine));
2469
- std::vector<BackupInfo> backup_info;
2470
- read_only_backup_engine->GetBackupInfo(&backup_info);
2471
- ASSERT_EQ(backup_info.size(), 2U);
2656
+ bool makeThrottler = std::get<0>(GetParam());
2657
+ if (makeThrottler) {
2658
+ engine_options_->backup_rate_limiter = backupThrottler;
2659
+ }
2472
2660
 
2473
- RestoreOptions restore_options(false);
2474
- ASSERT_OK(read_only_backup_engine->RestoreDBFromLatestBackup(
2475
- dbname_, dbname_, restore_options));
2476
- delete read_only_backup_engine;
2477
- std::vector<std::string> should_have_written;
2478
- test_backup_env_->AssertWrittenFiles(should_have_written);
2661
+ bool is_single_threaded = std::get<1>(GetParam()) == 0 ? true : false;
2662
+ engine_options_->max_background_operations = is_single_threaded ? 1 : 10;
2479
2663
 
2480
- DB* db = OpenDB();
2481
- AssertExists(db, 0, 200);
2482
- delete db;
2483
- }
2664
+ const std::uint64_t backup_rate_limiter_limit = std::get<2>(GetParam()).first;
2665
+ if (makeThrottler) {
2666
+ engine_options_->backup_rate_limiter->SetBytesPerSecond(
2667
+ backup_rate_limiter_limit);
2668
+ } else {
2669
+ engine_options_->backup_rate_limit = backup_rate_limiter_limit;
2670
+ }
2484
2671
 
2485
- TEST_F(BackupableDBTest, ProgressCallbackDuringBackup) {
2486
- DestroyDB(dbname_, options_);
2487
- OpenDBAndBackupEngine(true);
2488
- FillDB(db_.get(), 0, 100);
2489
- bool is_callback_invoked = false;
2490
- ASSERT_OK(backup_engine_->CreateNewBackup(
2491
- db_.get(), true,
2492
- [&is_callback_invoked]() { is_callback_invoked = true; }));
2672
+ DestroyDB(dbname_, Options());
2673
+ OpenDBAndBackupEngine(true /* destroy_old_data */);
2674
+ FillDB(db_.get(), 0, 100000);
2675
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2676
+ false /* flush_before_backup */));
2493
2677
 
2494
- ASSERT_TRUE(is_callback_invoked);
2678
+ std::vector<BackupInfo> backup_infos;
2679
+ BackupInfo backup_info;
2680
+ backup_engine_->GetBackupInfo(&backup_infos);
2681
+ ASSERT_EQ(1, backup_infos.size());
2682
+ const int backup_id = 1;
2683
+ ASSERT_EQ(backup_id, backup_infos[0].backup_id);
2684
+ ASSERT_OK(backup_engine_->GetBackupInfo(backup_id, &backup_info,
2685
+ true /* include_file_details */));
2686
+
2687
+ std::uint64_t bytes_read_during_verify_backup = 0;
2688
+ for (BackupFileInfo backup_file_info : backup_info.file_details) {
2689
+ bytes_read_during_verify_backup += backup_file_info.size;
2690
+ }
2691
+
2692
+ auto start_verify_backup = db_chroot_env_->NowMicros();
2693
+ ASSERT_OK(
2694
+ backup_engine_->VerifyBackup(backup_id, true /* verify_with_checksum */));
2695
+ auto verify_backup_time = db_chroot_env_->NowMicros() - start_verify_backup;
2696
+ auto rate_limited_verify_backup_time =
2697
+ (bytes_read_during_verify_backup * kMicrosPerSec) /
2698
+ backup_rate_limiter_limit;
2699
+
2700
+ if (makeThrottler) {
2701
+ EXPECT_GE(verify_backup_time, 0.8 * rate_limited_verify_backup_time);
2702
+ }
2495
2703
  CloseDBAndBackupEngine();
2496
- DestroyDB(dbname_, options_);
2704
+ AssertBackupConsistency(backup_id, 0, 100000, 100010);
2705
+ DestroyDB(dbname_, Options());
2497
2706
  }
2498
2707
 
2499
- TEST_F(BackupableDBTest, GarbageCollectionBeforeBackup) {
2500
- DestroyDB(dbname_, options_);
2501
- OpenDBAndBackupEngine(true);
2708
+ TEST_P(BackupEngineRateLimitingTestWithParam, RateLimitingChargeReadInBackup) {
2709
+ bool is_single_threaded = std::get<1>(GetParam()) == 0 ? true : false;
2710
+ engine_options_->max_background_operations = is_single_threaded ? 1 : 10;
2502
2711
 
2503
- ASSERT_OK(backup_chroot_env_->CreateDirIfMissing(backupdir_ + "/shared"));
2504
- std::string file_five = backupdir_ + "/shared/000008.sst";
2505
- std::string file_five_contents = "I'm not really a sst file";
2506
- // this depends on the fact that 00008.sst is the first file created by the DB
2507
- ASSERT_OK(file_manager_->WriteToFile(file_five, file_five_contents));
2712
+ const std::uint64_t backup_rate_limiter_limit = std::get<2>(GetParam()).first;
2713
+ std::shared_ptr<RateLimiter> backup_rate_limiter(NewGenericRateLimiter(
2714
+ backup_rate_limiter_limit, 100 * 1000 /* refill_period_us */,
2715
+ 10 /* fairness */, RateLimiter::Mode::kWritesOnly /* mode */));
2716
+ engine_options_->backup_rate_limiter = backup_rate_limiter;
2508
2717
 
2509
- FillDB(db_.get(), 0, 100);
2510
- // backup overwrites file 000008.sst
2511
- ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2718
+ DestroyDB(dbname_, Options());
2719
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
2720
+ kShareWithChecksum /* shared_option */);
2721
+ FillDB(db_.get(), 0, 10);
2722
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2723
+ false /* flush_before_backup */));
2724
+ std::int64_t total_bytes_through_with_no_read_charged =
2725
+ backup_rate_limiter->GetTotalBytesThrough();
2726
+ CloseBackupEngine();
2512
2727
 
2513
- std::string new_file_five_contents;
2514
- ASSERT_OK(ReadFileToString(backup_chroot_env_.get(), file_five,
2728
+ backup_rate_limiter.reset(NewGenericRateLimiter(
2729
+ backup_rate_limiter_limit, 100 * 1000 /* refill_period_us */,
2730
+ 10 /* fairness */, RateLimiter::Mode::kAllIo /* mode */));
2731
+ engine_options_->backup_rate_limiter = backup_rate_limiter;
2732
+
2733
+ OpenBackupEngine(true);
2734
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2735
+ false /* flush_before_backup */));
2736
+ std::int64_t total_bytes_through_with_read_charged =
2737
+ backup_rate_limiter->GetTotalBytesThrough();
2738
+ EXPECT_GT(total_bytes_through_with_read_charged,
2739
+ total_bytes_through_with_no_read_charged);
2740
+ CloseDBAndBackupEngine();
2741
+ AssertBackupConsistency(1, 0, 10, 20);
2742
+ DestroyDB(dbname_, Options());
2743
+ }
2744
+
2745
+ TEST_P(BackupEngineRateLimitingTestWithParam, RateLimitingChargeReadInRestore) {
2746
+ bool is_single_threaded = std::get<1>(GetParam()) == 0 ? true : false;
2747
+ engine_options_->max_background_operations = is_single_threaded ? 1 : 10;
2748
+
2749
+ const std::uint64_t restore_rate_limiter_limit =
2750
+ std::get<2>(GetParam()).second;
2751
+ std::shared_ptr<RateLimiter> restore_rate_limiter(NewGenericRateLimiter(
2752
+ restore_rate_limiter_limit, 100 * 1000 /* refill_period_us */,
2753
+ 10 /* fairness */, RateLimiter::Mode::kWritesOnly /* mode */));
2754
+ engine_options_->restore_rate_limiter = restore_rate_limiter;
2755
+
2756
+ DestroyDB(dbname_, Options());
2757
+ OpenDBAndBackupEngine(true /* destroy_old_data */);
2758
+ FillDB(db_.get(), 0, 10);
2759
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2760
+ false /* flush_before_backup */));
2761
+ CloseDBAndBackupEngine();
2762
+ DestroyDB(dbname_, Options());
2763
+
2764
+ OpenBackupEngine(false /* destroy_old_data */);
2765
+ ASSERT_OK(backup_engine_->RestoreDBFromLatestBackup(dbname_, dbname_));
2766
+ std::int64_t total_bytes_through_with_no_read_charged =
2767
+ restore_rate_limiter->GetTotalBytesThrough();
2768
+ CloseBackupEngine();
2769
+ DestroyDB(dbname_, Options());
2770
+
2771
+ restore_rate_limiter.reset(NewGenericRateLimiter(
2772
+ restore_rate_limiter_limit, 100 * 1000 /* refill_period_us */,
2773
+ 10 /* fairness */, RateLimiter::Mode::kAllIo /* mode */));
2774
+ engine_options_->restore_rate_limiter = restore_rate_limiter;
2775
+
2776
+ OpenBackupEngine(false /* destroy_old_data */);
2777
+ ASSERT_OK(backup_engine_->RestoreDBFromLatestBackup(dbname_, dbname_));
2778
+ std::int64_t total_bytes_through_with_read_charged =
2779
+ restore_rate_limiter->GetTotalBytesThrough();
2780
+ EXPECT_EQ(total_bytes_through_with_read_charged,
2781
+ total_bytes_through_with_no_read_charged * 2);
2782
+ CloseBackupEngine();
2783
+ AssertBackupConsistency(1, 0, 10, 20);
2784
+ DestroyDB(dbname_, Options());
2785
+ }
2786
+
2787
+ TEST_P(BackupEngineRateLimitingTestWithParam,
2788
+ RateLimitingChargeReadInInitialize) {
2789
+ bool is_single_threaded = std::get<1>(GetParam()) == 0 ? true : false;
2790
+ engine_options_->max_background_operations = is_single_threaded ? 1 : 10;
2791
+
2792
+ const std::uint64_t backup_rate_limiter_limit = std::get<2>(GetParam()).first;
2793
+ std::shared_ptr<RateLimiter> backup_rate_limiter(NewGenericRateLimiter(
2794
+ backup_rate_limiter_limit, 100 * 1000 /* refill_period_us */,
2795
+ 10 /* fairness */, RateLimiter::Mode::kAllIo /* mode */));
2796
+ engine_options_->backup_rate_limiter = backup_rate_limiter;
2797
+
2798
+ DestroyDB(dbname_, Options());
2799
+ OpenDBAndBackupEngine(true /* destroy_old_data */);
2800
+ FillDB(db_.get(), 0, 10);
2801
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2802
+ false /* flush_before_backup */));
2803
+ CloseDBAndBackupEngine();
2804
+ AssertBackupConsistency(1, 0, 10, 20);
2805
+
2806
+ std::int64_t total_bytes_through_before_initialize =
2807
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2808
+ OpenDBAndBackupEngine(false /* destroy_old_data */);
2809
+ // We charge read in BackupEngineImpl::BackupMeta::LoadFromFile,
2810
+ // which is called in BackupEngineImpl::Initialize() during
2811
+ // OpenBackupEngine(false)
2812
+ EXPECT_GT(engine_options_->backup_rate_limiter->GetTotalBytesThrough(),
2813
+ total_bytes_through_before_initialize);
2814
+ CloseDBAndBackupEngine();
2815
+ DestroyDB(dbname_, Options());
2816
+ }
2817
+
2818
+ class BackupEngineRateLimitingTestWithParam2
2819
+ : public BackupEngineTest,
2820
+ public testing::WithParamInterface<
2821
+ std::tuple<std::pair<uint64_t, uint64_t> /* limits */>> {
2822
+ public:
2823
+ BackupEngineRateLimitingTestWithParam2() {}
2824
+ };
2825
+
2826
+ INSTANTIATE_TEST_CASE_P(
2827
+ LowRefillBytesPerPeriod, BackupEngineRateLimitingTestWithParam2,
2828
+ ::testing::Values(std::make_tuple(std::make_pair(1, 1))));
2829
+ // To verify we don't request over-sized bytes relative to
2830
+ // refill_bytes_per_period_ in each RateLimiter::Request() called in
2831
+ // BackupEngine through verifying we don't trigger assertion
2832
+ // failure on over-sized request in GenericRateLimiter in debug builds
2833
+ TEST_P(BackupEngineRateLimitingTestWithParam2,
2834
+ RateLimitingWithLowRefillBytesPerPeriod) {
2835
+ SpecialEnv special_env(Env::Default(), /*time_elapse_only_sleep*/ true);
2836
+
2837
+ engine_options_->max_background_operations = 1;
2838
+ const uint64_t backup_rate_limiter_limit = std::get<0>(GetParam()).first;
2839
+ std::shared_ptr<RateLimiter> backup_rate_limiter(
2840
+ std::make_shared<GenericRateLimiter>(
2841
+ backup_rate_limiter_limit, 1000 * 1000 /* refill_period_us */,
2842
+ 10 /* fairness */, RateLimiter::Mode::kAllIo /* mode */,
2843
+ special_env.GetSystemClock(), false /* auto_tuned */));
2844
+
2845
+ engine_options_->backup_rate_limiter = backup_rate_limiter;
2846
+
2847
+ const uint64_t restore_rate_limiter_limit = std::get<0>(GetParam()).second;
2848
+ std::shared_ptr<RateLimiter> restore_rate_limiter(
2849
+ std::make_shared<GenericRateLimiter>(
2850
+ restore_rate_limiter_limit, 1000 * 1000 /* refill_period_us */,
2851
+ 10 /* fairness */, RateLimiter::Mode::kAllIo /* mode */,
2852
+ special_env.GetSystemClock(), false /* auto_tuned */));
2853
+
2854
+ engine_options_->restore_rate_limiter = restore_rate_limiter;
2855
+
2856
+ // Rate limiter uses `CondVar::TimedWait()`, which does not have access to the
2857
+ // `Env` to advance its time according to the fake wait duration. The
2858
+ // workaround is to install a callback that advance the `Env`'s mock time.
2859
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
2860
+ "GenericRateLimiter::Request:PostTimedWait", [&](void* arg) {
2861
+ int64_t time_waited_us = *static_cast<int64_t*>(arg);
2862
+ special_env.SleepForMicroseconds(static_cast<int>(time_waited_us));
2863
+ });
2864
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
2865
+
2866
+ DestroyDB(dbname_, Options());
2867
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
2868
+ kShareWithChecksum /* shared_option */);
2869
+
2870
+ FillDB(db_.get(), 0, 100);
2871
+ int64_t total_bytes_through_before_backup =
2872
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2873
+ EXPECT_OK(backup_engine_->CreateNewBackup(db_.get(),
2874
+ false /* flush_before_backup */));
2875
+ int64_t total_bytes_through_after_backup =
2876
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2877
+ ASSERT_GT(total_bytes_through_after_backup,
2878
+ total_bytes_through_before_backup);
2879
+
2880
+ std::vector<BackupInfo> backup_infos;
2881
+ BackupInfo backup_info;
2882
+ backup_engine_->GetBackupInfo(&backup_infos);
2883
+ ASSERT_EQ(1, backup_infos.size());
2884
+ const int backup_id = 1;
2885
+ ASSERT_EQ(backup_id, backup_infos[0].backup_id);
2886
+ ASSERT_OK(backup_engine_->GetBackupInfo(backup_id, &backup_info,
2887
+ true /* include_file_details */));
2888
+ int64_t total_bytes_through_before_verify_backup =
2889
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2890
+ EXPECT_OK(
2891
+ backup_engine_->VerifyBackup(backup_id, true /* verify_with_checksum */));
2892
+ int64_t total_bytes_through_after_verify_backup =
2893
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2894
+ ASSERT_GT(total_bytes_through_after_verify_backup,
2895
+ total_bytes_through_before_verify_backup);
2896
+
2897
+ CloseDBAndBackupEngine();
2898
+ AssertBackupConsistency(backup_id, 0, 100, 101);
2899
+
2900
+ int64_t total_bytes_through_before_initialize =
2901
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2902
+ OpenDBAndBackupEngine(false /* destroy_old_data */);
2903
+ // We charge read in BackupEngineImpl::BackupMeta::LoadFromFile,
2904
+ // which is called in BackupEngineImpl::Initialize() during
2905
+ // OpenBackupEngine(false)
2906
+ int64_t total_bytes_through_after_initialize =
2907
+ engine_options_->backup_rate_limiter->GetTotalBytesThrough();
2908
+ ASSERT_GT(total_bytes_through_after_initialize,
2909
+ total_bytes_through_before_initialize);
2910
+ CloseDBAndBackupEngine();
2911
+
2912
+ DestroyDB(dbname_, Options());
2913
+ OpenBackupEngine(false /* destroy_old_data */);
2914
+ int64_t total_bytes_through_before_restore =
2915
+ engine_options_->restore_rate_limiter->GetTotalBytesThrough();
2916
+ EXPECT_OK(backup_engine_->RestoreDBFromLatestBackup(dbname_, dbname_));
2917
+ int64_t total_bytes_through_after_restore =
2918
+ engine_options_->restore_rate_limiter->GetTotalBytesThrough();
2919
+ ASSERT_GT(total_bytes_through_after_restore,
2920
+ total_bytes_through_before_restore);
2921
+ CloseBackupEngine();
2922
+
2923
+ DestroyDB(dbname_, Options());
2924
+
2925
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
2926
+ ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->ClearCallBack(
2927
+ "GenericRateLimiter::Request:PostTimedWait");
2928
+ }
2929
+
2930
+ #endif // !defined(ROCKSDB_VALGRIND_RUN) || defined(ROCKSDB_FULL_VALGRIND_RUN)
2931
+
2932
+ TEST_F(BackupEngineTest, ReadOnlyBackupEngine) {
2933
+ DestroyDB(dbname_, options_);
2934
+ OpenDBAndBackupEngine(true);
2935
+ FillDB(db_.get(), 0, 100);
2936
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2937
+ FillDB(db_.get(), 100, 200);
2938
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2939
+ CloseDBAndBackupEngine();
2940
+ DestroyDB(dbname_, options_);
2941
+
2942
+ engine_options_->destroy_old_data = false;
2943
+ test_backup_fs_->ClearWrittenFiles();
2944
+ test_backup_fs_->SetLimitDeleteFiles(0);
2945
+ BackupEngineReadOnly* read_only_backup_engine;
2946
+ ASSERT_OK(BackupEngineReadOnly::Open(db_chroot_env_.get(), *engine_options_,
2947
+ &read_only_backup_engine));
2948
+ std::vector<BackupInfo> backup_info;
2949
+ read_only_backup_engine->GetBackupInfo(&backup_info);
2950
+ ASSERT_EQ(backup_info.size(), 2U);
2951
+
2952
+ RestoreOptions restore_options(false);
2953
+ ASSERT_OK(read_only_backup_engine->RestoreDBFromLatestBackup(
2954
+ dbname_, dbname_, restore_options));
2955
+ delete read_only_backup_engine;
2956
+ std::vector<std::string> should_have_written;
2957
+ test_backup_fs_->AssertWrittenFiles(should_have_written);
2958
+
2959
+ DB* db = OpenDB();
2960
+ AssertExists(db, 0, 200);
2961
+ delete db;
2962
+ }
2963
+
2964
+ TEST_F(BackupEngineTest, OpenBackupAsReadOnlyDB) {
2965
+ DestroyDB(dbname_, options_);
2966
+ options_.write_dbid_to_manifest = false;
2967
+
2968
+ OpenDBAndBackupEngine(true);
2969
+ FillDB(db_.get(), 0, 100);
2970
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), /*flush*/ false));
2971
+
2972
+ options_.write_dbid_to_manifest = true; // exercises some read-only DB code
2973
+ CloseAndReopenDB();
2974
+
2975
+ FillDB(db_.get(), 100, 200);
2976
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), /*flush*/ false));
2977
+ db_.reset(); // CloseDB
2978
+ DestroyDB(dbname_, options_);
2979
+ BackupInfo backup_info;
2980
+ // First, check that we get empty fields without include_file_details
2981
+ ASSERT_OK(backup_engine_->GetBackupInfo(/*id*/ 1U, &backup_info,
2982
+ /*with file details*/ false));
2983
+ ASSERT_EQ(backup_info.name_for_open, "");
2984
+ ASSERT_FALSE(backup_info.env_for_open);
2985
+
2986
+ // Now for the real test
2987
+ backup_info = BackupInfo();
2988
+ ASSERT_OK(backup_engine_->GetBackupInfo(/*id*/ 1U, &backup_info,
2989
+ /*with file details*/ true));
2990
+
2991
+ // Caution: DBOptions only holds a raw pointer to Env, so something else
2992
+ // must keep it alive.
2993
+ // Case 1: Keeping BackupEngine open suffices to keep Env alive
2994
+ DB* db = nullptr;
2995
+ Options opts = options_;
2996
+ // Ensure some key defaults are set
2997
+ opts.wal_dir = "";
2998
+ opts.create_if_missing = false;
2999
+ opts.info_log.reset();
3000
+
3001
+ opts.env = backup_info.env_for_open.get();
3002
+ std::string name = backup_info.name_for_open;
3003
+ backup_info = BackupInfo();
3004
+ ASSERT_OK(DB::OpenForReadOnly(opts, name, &db));
3005
+
3006
+ AssertExists(db, 0, 100);
3007
+ AssertEmpty(db, 100, 200);
3008
+
3009
+ delete db;
3010
+ db = nullptr;
3011
+
3012
+ // Case 2: Keeping BackupInfo alive rather than BackupEngine also suffices
3013
+ ASSERT_OK(backup_engine_->GetBackupInfo(/*id*/ 2U, &backup_info,
3014
+ /*with file details*/ true));
3015
+ CloseBackupEngine();
3016
+ opts.create_if_missing = true; // check also OK (though pointless)
3017
+ opts.env = backup_info.env_for_open.get();
3018
+ name = backup_info.name_for_open;
3019
+ // Note: keeping backup_info alive
3020
+ ASSERT_OK(DB::OpenForReadOnly(opts, name, &db));
3021
+
3022
+ AssertExists(db, 0, 200);
3023
+ delete db;
3024
+ db = nullptr;
3025
+
3026
+ // Now try opening read-write and make sure it fails, for safety.
3027
+ ASSERT_TRUE(DB::Open(opts, name, &db).IsIOError());
3028
+ }
3029
+
3030
+ TEST_F(BackupEngineTest, ProgressCallbackDuringBackup) {
3031
+ DestroyDB(dbname_, options_);
3032
+ // Too big for this small DB
3033
+ engine_options_->callback_trigger_interval_size = 100000;
3034
+ OpenDBAndBackupEngine(true);
3035
+ FillDB(db_.get(), 0, 100);
3036
+ bool is_callback_invoked = false;
3037
+ ASSERT_OK(backup_engine_->CreateNewBackup(
3038
+ db_.get(), true,
3039
+ [&is_callback_invoked]() { is_callback_invoked = true; }));
3040
+ ASSERT_FALSE(is_callback_invoked);
3041
+ CloseBackupEngine();
3042
+
3043
+ // Easily small enough for this small DB
3044
+ engine_options_->callback_trigger_interval_size = 1000;
3045
+ OpenBackupEngine();
3046
+ ASSERT_OK(backup_engine_->CreateNewBackup(
3047
+ db_.get(), true,
3048
+ [&is_callback_invoked]() { is_callback_invoked = true; }));
3049
+ ASSERT_TRUE(is_callback_invoked);
3050
+ CloseDBAndBackupEngine();
3051
+ DestroyDB(dbname_, options_);
3052
+ }
3053
+
3054
+ TEST_F(BackupEngineTest, GarbageCollectionBeforeBackup) {
3055
+ DestroyDB(dbname_, options_);
3056
+ OpenDBAndBackupEngine(true);
3057
+
3058
+ ASSERT_OK(backup_chroot_env_->CreateDirIfMissing(backupdir_ + "/shared"));
3059
+ std::string file_five = backupdir_ + "/shared/000009.sst";
3060
+ std::string file_five_contents = "I'm not really a sst file";
3061
+ // this depends on the fact that 00009.sst is the first file created by the DB
3062
+ ASSERT_OK(file_manager_->WriteToFile(file_five, file_five_contents));
3063
+
3064
+ FillDB(db_.get(), 0, 100);
3065
+ // backup overwrites file 000009.sst
3066
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3067
+
3068
+ std::string new_file_five_contents;
3069
+ ASSERT_OK(ReadFileToString(backup_chroot_env_.get(), file_five,
2515
3070
  &new_file_five_contents));
2516
- // file 000008.sst was overwritten
3071
+ // file 000009.sst was overwritten
2517
3072
  ASSERT_TRUE(new_file_five_contents != file_five_contents);
2518
3073
 
2519
3074
  CloseDBAndBackupEngine();
@@ -2522,31 +3077,31 @@ TEST_F(BackupableDBTest, GarbageCollectionBeforeBackup) {
2522
3077
  }
2523
3078
 
2524
3079
  // Test that we properly propagate Env failures
2525
- TEST_F(BackupableDBTest, EnvFailures) {
3080
+ TEST_F(BackupEngineTest, EnvFailures) {
2526
3081
  BackupEngine* backup_engine;
2527
3082
 
2528
3083
  // get children failure
2529
3084
  {
2530
- test_backup_env_->SetGetChildrenFailure(true);
2531
- ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
3085
+ test_backup_fs_->SetGetChildrenFailure(true);
3086
+ ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
2532
3087
  &backup_engine));
2533
- test_backup_env_->SetGetChildrenFailure(false);
3088
+ test_backup_fs_->SetGetChildrenFailure(false);
2534
3089
  }
2535
3090
 
2536
3091
  // created dir failure
2537
3092
  {
2538
- test_backup_env_->SetCreateDirIfMissingFailure(true);
2539
- ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
3093
+ test_backup_fs_->SetCreateDirIfMissingFailure(true);
3094
+ ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
2540
3095
  &backup_engine));
2541
- test_backup_env_->SetCreateDirIfMissingFailure(false);
3096
+ test_backup_fs_->SetCreateDirIfMissingFailure(false);
2542
3097
  }
2543
3098
 
2544
3099
  // new directory failure
2545
3100
  {
2546
- test_backup_env_->SetNewDirectoryFailure(true);
2547
- ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
3101
+ test_backup_fs_->SetNewDirectoryFailure(true);
3102
+ ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
2548
3103
  &backup_engine));
2549
- test_backup_env_->SetNewDirectoryFailure(false);
3104
+ test_backup_fs_->SetNewDirectoryFailure(false);
2550
3105
  }
2551
3106
 
2552
3107
  // Read from meta-file failure
@@ -2556,18 +3111,18 @@ TEST_F(BackupableDBTest, EnvFailures) {
2556
3111
  FillDB(db_.get(), 0, 100);
2557
3112
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2558
3113
  CloseDBAndBackupEngine();
2559
- test_backup_env_->SetDummySequentialFile(true);
2560
- test_backup_env_->SetDummySequentialFileFailReads(true);
2561
- backupable_options_->destroy_old_data = false;
2562
- ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
3114
+ test_backup_fs_->SetDummySequentialFile(true);
3115
+ test_backup_fs_->SetDummySequentialFileFailReads(true);
3116
+ engine_options_->destroy_old_data = false;
3117
+ ASSERT_NOK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
2563
3118
  &backup_engine));
2564
- test_backup_env_->SetDummySequentialFile(false);
2565
- test_backup_env_->SetDummySequentialFileFailReads(false);
3119
+ test_backup_fs_->SetDummySequentialFile(false);
3120
+ test_backup_fs_->SetDummySequentialFileFailReads(false);
2566
3121
  }
2567
3122
 
2568
3123
  // no failure
2569
3124
  {
2570
- ASSERT_OK(BackupEngine::Open(test_db_env_.get(), *backupable_options_,
3125
+ ASSERT_OK(BackupEngine::Open(test_db_env_.get(), *engine_options_,
2571
3126
  &backup_engine));
2572
3127
  delete backup_engine;
2573
3128
  }
@@ -2575,7 +3130,7 @@ TEST_F(BackupableDBTest, EnvFailures) {
2575
3130
 
2576
3131
  // Verify manifest can roll while a backup is being created with the old
2577
3132
  // manifest.
2578
- TEST_F(BackupableDBTest, ChangeManifestDuringBackupCreation) {
3133
+ TEST_F(BackupEngineTest, ChangeManifestDuringBackupCreation) {
2579
3134
  DestroyDB(dbname_, options_);
2580
3135
  options_.max_manifest_file_size = 0; // always rollover manifest for file add
2581
3136
  OpenDBAndBackupEngine(true);
@@ -2606,6 +3161,10 @@ TEST_F(BackupableDBTest, ChangeManifestDuringBackupCreation) {
2606
3161
  FillDB(db_.get(), 0, 100, kAutoFlushOnly);
2607
3162
  ASSERT_OK(db_chroot_env_->FileExists(prev_manifest_path));
2608
3163
  ASSERT_OK(db_->Flush(FlushOptions()));
3164
+ // Even though manual flush completed above, the background thread may not
3165
+ // have finished its cleanup work. `TEST_WaitForBackgroundWork()` will wait
3166
+ // until all the background thread's work has completed, including cleanup.
3167
+ ASSERT_OK(db_impl->TEST_WaitForBackgroundWork());
2609
3168
  ASSERT_TRUE(db_chroot_env_->FileExists(prev_manifest_path).IsNotFound());
2610
3169
 
2611
3170
  CloseDBAndBackupEngine();
@@ -2614,42 +3173,57 @@ TEST_F(BackupableDBTest, ChangeManifestDuringBackupCreation) {
2614
3173
  }
2615
3174
 
2616
3175
  // see https://github.com/facebook/rocksdb/issues/921
2617
- TEST_F(BackupableDBTest, Issue921Test) {
3176
+ TEST_F(BackupEngineTest, Issue921Test) {
2618
3177
  BackupEngine* backup_engine;
2619
- backupable_options_->share_table_files = false;
3178
+ engine_options_->share_table_files = false;
2620
3179
  ASSERT_OK(
2621
- backup_chroot_env_->CreateDirIfMissing(backupable_options_->backup_dir));
2622
- backupable_options_->backup_dir += "/new_dir";
2623
- ASSERT_OK(BackupEngine::Open(backup_chroot_env_.get(), *backupable_options_,
3180
+ backup_chroot_env_->CreateDirIfMissing(engine_options_->backup_dir));
3181
+ engine_options_->backup_dir += "/new_dir";
3182
+ ASSERT_OK(BackupEngine::Open(backup_chroot_env_.get(), *engine_options_,
2624
3183
  &backup_engine));
2625
3184
 
2626
3185
  delete backup_engine;
2627
3186
  }
2628
3187
 
2629
- TEST_F(BackupableDBTest, BackupWithMetadata) {
3188
+ TEST_F(BackupEngineTest, BackupWithMetadata) {
2630
3189
  const int keys_iteration = 5000;
2631
3190
  OpenDBAndBackupEngine(true);
2632
3191
  // create five backups
2633
3192
  for (int i = 0; i < 5; ++i) {
2634
3193
  const std::string metadata = std::to_string(i);
2635
3194
  FillDB(db_.get(), keys_iteration * i, keys_iteration * (i + 1));
2636
- ASSERT_OK(
2637
- backup_engine_->CreateNewBackupWithMetadata(db_.get(), metadata, true));
3195
+ // Here also test CreateNewBackupWithMetadata with CreateBackupOptions
3196
+ // and outputting saved BackupID.
3197
+ CreateBackupOptions opts;
3198
+ opts.flush_before_backup = true;
3199
+ BackupID new_id = 0;
3200
+ ASSERT_OK(backup_engine_->CreateNewBackupWithMetadata(opts, db_.get(),
3201
+ metadata, &new_id));
3202
+ ASSERT_EQ(new_id, static_cast<BackupID>(i + 1));
2638
3203
  }
2639
3204
  CloseDBAndBackupEngine();
2640
3205
 
2641
3206
  OpenDBAndBackupEngine();
2642
- std::vector<BackupInfo> backup_infos;
2643
- backup_engine_->GetBackupInfo(&backup_infos);
2644
- ASSERT_EQ(5, backup_infos.size());
3207
+ { // Verify in bulk BackupInfo
3208
+ std::vector<BackupInfo> backup_infos;
3209
+ backup_engine_->GetBackupInfo(&backup_infos);
3210
+ ASSERT_EQ(5, backup_infos.size());
3211
+ for (int i = 0; i < 5; i++) {
3212
+ ASSERT_EQ(std::to_string(i), backup_infos[i].app_metadata);
3213
+ }
3214
+ }
3215
+ // Also verify in individual BackupInfo
2645
3216
  for (int i = 0; i < 5; i++) {
2646
- ASSERT_EQ(std::to_string(i), backup_infos[i].app_metadata);
3217
+ BackupInfo backup_info;
3218
+ ASSERT_OK(backup_engine_->GetBackupInfo(static_cast<BackupID>(i + 1),
3219
+ &backup_info));
3220
+ ASSERT_EQ(std::to_string(i), backup_info.app_metadata);
2647
3221
  }
2648
3222
  CloseDBAndBackupEngine();
2649
3223
  DestroyDB(dbname_, options_);
2650
3224
  }
2651
3225
 
2652
- TEST_F(BackupableDBTest, BinaryMetadata) {
3226
+ TEST_F(BackupEngineTest, BinaryMetadata) {
2653
3227
  OpenDBAndBackupEngine(true);
2654
3228
  std::string binaryMetadata = "abc\ndef";
2655
3229
  binaryMetadata.push_back('\0');
@@ -2667,7 +3241,7 @@ TEST_F(BackupableDBTest, BinaryMetadata) {
2667
3241
  DestroyDB(dbname_, options_);
2668
3242
  }
2669
3243
 
2670
- TEST_F(BackupableDBTest, MetadataTooLarge) {
3244
+ TEST_F(BackupEngineTest, MetadataTooLarge) {
2671
3245
  OpenDBAndBackupEngine(true);
2672
3246
  std::string largeMetadata(1024 * 1024 + 1, 0);
2673
3247
  ASSERT_NOK(
@@ -2676,7 +3250,379 @@ TEST_F(BackupableDBTest, MetadataTooLarge) {
2676
3250
  DestroyDB(dbname_, options_);
2677
3251
  }
2678
3252
 
2679
- TEST_F(BackupableDBTest, LimitBackupsOpened) {
3253
+ TEST_F(BackupEngineTest, MetaSchemaVersion2_SizeCorruption) {
3254
+ engine_options_->schema_version = 1;
3255
+ OpenDBAndBackupEngine(/*destroy_old_data*/ true);
3256
+
3257
+ // Backup 1: no future schema, no sizes, with checksums
3258
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3259
+
3260
+ CloseDBAndBackupEngine();
3261
+ engine_options_->schema_version = 2;
3262
+ OpenDBAndBackupEngine(/*destroy_old_data*/ false);
3263
+
3264
+ // Backup 2: no checksums, no sizes
3265
+ TEST_BackupMetaSchemaOptions test_opts;
3266
+ test_opts.crc32c_checksums = false;
3267
+ test_opts.file_sizes = false;
3268
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3269
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3270
+
3271
+ // Backup 3: no checksums, with sizes
3272
+ test_opts.file_sizes = true;
3273
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3274
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3275
+
3276
+ // Backup 4: with checksums and sizes
3277
+ test_opts.crc32c_checksums = true;
3278
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3279
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3280
+
3281
+ CloseDBAndBackupEngine();
3282
+
3283
+ // Corrupt all the CURRENT files with the wrong size
3284
+ const std::string private_dir = backupdir_ + "/private";
3285
+
3286
+ for (int id = 1; id <= 3; ++id) {
3287
+ ASSERT_OK(file_manager_->WriteToFile(
3288
+ private_dir + "/" + ToString(id) + "/CURRENT", "x"));
3289
+ }
3290
+ // Except corrupt Backup 4 with same size CURRENT file
3291
+ {
3292
+ uint64_t size = 0;
3293
+ ASSERT_OK(test_backup_env_->GetFileSize(private_dir + "/4/CURRENT", &size));
3294
+ ASSERT_OK(file_manager_->WriteToFile(private_dir + "/4/CURRENT",
3295
+ std::string(size, 'x')));
3296
+ }
3297
+
3298
+ OpenBackupEngine();
3299
+
3300
+ // Only the one with sizes in metadata will be immediately detected
3301
+ // as corrupt
3302
+ std::vector<BackupID> corrupted;
3303
+ backup_engine_->GetCorruptedBackups(&corrupted);
3304
+ ASSERT_EQ(corrupted.size(), 1);
3305
+ ASSERT_EQ(corrupted[0], 3);
3306
+
3307
+ // Size corruption detected on Restore with checksum
3308
+ ASSERT_TRUE(backup_engine_->RestoreDBFromBackup(1 /*id*/, dbname_, dbname_)
3309
+ .IsCorruption());
3310
+
3311
+ // Size corruption not detected without checksums nor sizes
3312
+ ASSERT_OK(backup_engine_->RestoreDBFromBackup(2 /*id*/, dbname_, dbname_));
3313
+
3314
+ // Non-size corruption detected on Restore with checksum
3315
+ ASSERT_TRUE(backup_engine_->RestoreDBFromBackup(4 /*id*/, dbname_, dbname_)
3316
+ .IsCorruption());
3317
+
3318
+ CloseBackupEngine();
3319
+ }
3320
+
3321
+ TEST_F(BackupEngineTest, MetaSchemaVersion2_NotSupported) {
3322
+ engine_options_->schema_version = 2;
3323
+ TEST_BackupMetaSchemaOptions test_opts;
3324
+ std::string app_metadata = "abc\ndef";
3325
+
3326
+ OpenDBAndBackupEngine(true);
3327
+ // Start with supported
3328
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3329
+ ASSERT_OK(
3330
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3331
+
3332
+ // Because we are injecting badness with a TEST API, the badness is only
3333
+ // detected on attempt to restore.
3334
+ // Not supported versions
3335
+ test_opts.version = "3";
3336
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3337
+ ASSERT_OK(
3338
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3339
+ test_opts.version = "23.45.67";
3340
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3341
+ ASSERT_OK(
3342
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3343
+ test_opts.version = "2";
3344
+
3345
+ // Non-ignorable fields
3346
+ test_opts.meta_fields["ni::blah"] = "123";
3347
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3348
+ ASSERT_OK(
3349
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3350
+ test_opts.meta_fields.clear();
3351
+
3352
+ test_opts.file_fields["ni::123"] = "xyz";
3353
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3354
+ ASSERT_OK(
3355
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3356
+ test_opts.file_fields.clear();
3357
+
3358
+ test_opts.footer_fields["ni::123"] = "xyz";
3359
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3360
+ ASSERT_OK(
3361
+ backup_engine_->CreateNewBackupWithMetadata(db_.get(), app_metadata));
3362
+ test_opts.footer_fields.clear();
3363
+ CloseDBAndBackupEngine();
3364
+
3365
+ OpenBackupEngine();
3366
+ std::vector<BackupID> corrupted;
3367
+ backup_engine_->GetCorruptedBackups(&corrupted);
3368
+ ASSERT_EQ(corrupted.size(), 5);
3369
+
3370
+ ASSERT_OK(backup_engine_->RestoreDBFromLatestBackup(dbname_, dbname_));
3371
+ CloseBackupEngine();
3372
+ }
3373
+
3374
+ TEST_F(BackupEngineTest, MetaSchemaVersion2_Restore) {
3375
+ engine_options_->schema_version = 2;
3376
+ TEST_BackupMetaSchemaOptions test_opts;
3377
+ const int keys_iteration = 5000;
3378
+
3379
+ OpenDBAndBackupEngine(true, false, kShareWithChecksum);
3380
+ FillDB(db_.get(), 0, keys_iteration);
3381
+ // Start with minimum metadata to ensure it works without it being filled
3382
+ // based on shared files also in other backups with the metadata.
3383
+ test_opts.crc32c_checksums = false;
3384
+ test_opts.file_sizes = false;
3385
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3386
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3387
+ CloseDBAndBackupEngine();
3388
+
3389
+ AssertBackupConsistency(1 /* id */, 0, keys_iteration, keys_iteration * 2);
3390
+
3391
+ OpenDBAndBackupEngine(false /* destroy_old_data */, false,
3392
+ kShareWithChecksum);
3393
+ test_opts.file_sizes = true;
3394
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3395
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3396
+ CloseDBAndBackupEngine();
3397
+
3398
+ for (int id = 1; id <= 2; ++id) {
3399
+ AssertBackupConsistency(id, 0, keys_iteration, keys_iteration * 2);
3400
+ }
3401
+
3402
+ OpenDBAndBackupEngine(false /* destroy_old_data */, false,
3403
+ kShareWithChecksum);
3404
+ test_opts.crc32c_checksums = true;
3405
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3406
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3407
+ CloseDBAndBackupEngine();
3408
+
3409
+ for (int id = 1; id <= 3; ++id) {
3410
+ AssertBackupConsistency(id, 0, keys_iteration, keys_iteration * 2);
3411
+ }
3412
+
3413
+ OpenDBAndBackupEngine(false /* destroy_old_data */, false,
3414
+ kShareWithChecksum);
3415
+ // No TEST_EnableWriteFutureSchemaVersion2
3416
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3417
+ CloseDBAndBackupEngine();
3418
+
3419
+ for (int id = 1; id <= 4; ++id) {
3420
+ AssertBackupConsistency(id, 0, keys_iteration, keys_iteration * 2);
3421
+ }
3422
+
3423
+ OpenDBAndBackupEngine(false /* destroy_old_data */, false,
3424
+ kShareWithChecksum);
3425
+ // Minor version updates should be forward-compatible
3426
+ test_opts.version = "2.5.70";
3427
+ test_opts.meta_fields["asdf.3456"] = "-42";
3428
+ test_opts.meta_fields["__QRST"] = " 1 $ %%& ";
3429
+ test_opts.file_fields["z94._"] = "^\\";
3430
+ test_opts.file_fields["_7yyyyyyyyy"] = "111111111111";
3431
+ test_opts.footer_fields["Qwzn.tz89"] = "ASDF!!@# ##=\t ";
3432
+ test_opts.footer_fields["yes"] = "no!";
3433
+ TEST_SetBackupMetaSchemaOptions(backup_engine_.get(), test_opts);
3434
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
3435
+ CloseDBAndBackupEngine();
3436
+
3437
+ for (int id = 1; id <= 5; ++id) {
3438
+ AssertBackupConsistency(id, 0, keys_iteration, keys_iteration * 2);
3439
+ }
3440
+ }
3441
+
3442
+ TEST_F(BackupEngineTest, Concurrency) {
3443
+ // Check that we can simultaneously:
3444
+ // * Run several read operations in different threads on a single
3445
+ // BackupEngine object, and
3446
+ // * With another BackupEngine object on the same
3447
+ // backup_dir, run the same read operations in another thread, and
3448
+ // * With yet another BackupEngine object on the same
3449
+ // backup_dir, create two new backups in parallel threads.
3450
+ //
3451
+ // Because of the challenges of integrating this into db_stress,
3452
+ // this is a non-deterministic mini-stress test here instead.
3453
+
3454
+ // To check for a race condition in handling buffer size based on byte
3455
+ // burst limit, we need a (generous) rate limiter
3456
+ std::shared_ptr<RateLimiter> limiter{NewGenericRateLimiter(1000000000)};
3457
+ engine_options_->backup_rate_limiter = limiter;
3458
+ engine_options_->restore_rate_limiter = limiter;
3459
+
3460
+ OpenDBAndBackupEngine(true, false, kShareWithChecksum);
3461
+
3462
+ static constexpr int keys_iteration = 5000;
3463
+ FillDB(db_.get(), 0, keys_iteration);
3464
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3465
+
3466
+ FillDB(db_.get(), keys_iteration, 2 * keys_iteration);
3467
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
3468
+
3469
+ static constexpr int max_factor = 3;
3470
+ FillDB(db_.get(), 2 * keys_iteration, max_factor * keys_iteration);
3471
+ // will create another backup soon...
3472
+
3473
+ Options db_opts = options_;
3474
+ db_opts.wal_dir = "";
3475
+ db_opts.create_if_missing = false;
3476
+ BackupEngineOptions be_opts = *engine_options_;
3477
+ be_opts.destroy_old_data = false;
3478
+
3479
+ std::mt19937 rng{std::random_device()()};
3480
+
3481
+ std::array<std::thread, 4> read_threads;
3482
+ std::array<std::thread, 4> restore_verify_threads;
3483
+ for (uint32_t i = 0; i < read_threads.size(); ++i) {
3484
+ uint32_t sleep_micros = rng() % 100000;
3485
+ read_threads[i] =
3486
+ std::thread([this, i, sleep_micros, &db_opts, &be_opts,
3487
+ &restore_verify_threads, &limiter] {
3488
+ test_db_env_->SleepForMicroseconds(sleep_micros);
3489
+
3490
+ // Whether to also re-open the BackupEngine, potentially seeing
3491
+ // additional backups
3492
+ bool reopen = i == 3;
3493
+ // Whether we are going to restore "latest"
3494
+ bool latest = i > 1;
3495
+
3496
+ BackupEngine* my_be;
3497
+ if (reopen) {
3498
+ ASSERT_OK(BackupEngine::Open(test_db_env_.get(), be_opts, &my_be));
3499
+ } else {
3500
+ my_be = backup_engine_.get();
3501
+ }
3502
+
3503
+ // Verify metadata (we don't receive updates from concurrently
3504
+ // creating a new backup)
3505
+ std::vector<BackupInfo> infos;
3506
+ my_be->GetBackupInfo(&infos);
3507
+ const uint32_t count = static_cast<uint32_t>(infos.size());
3508
+ infos.clear();
3509
+ if (reopen) {
3510
+ ASSERT_GE(count, 2U);
3511
+ ASSERT_LE(count, 4U);
3512
+ fprintf(stderr, "Reopen saw %u backups\n", count);
3513
+ } else {
3514
+ ASSERT_EQ(count, 2U);
3515
+ }
3516
+ std::vector<BackupID> ids;
3517
+ my_be->GetCorruptedBackups(&ids);
3518
+ ASSERT_EQ(ids.size(), 0U);
3519
+
3520
+ // (Eventually, see below) Restore one of the backups, or "latest"
3521
+ std::string restore_db_dir = dbname_ + "/restore" + ToString(i);
3522
+ DestroyDir(test_db_env_.get(), restore_db_dir).PermitUncheckedError();
3523
+ BackupID to_restore;
3524
+ if (latest) {
3525
+ to_restore = count;
3526
+ } else {
3527
+ to_restore = i + 1;
3528
+ }
3529
+
3530
+ // Open restored DB to verify its contents, but test atomic restore
3531
+ // by doing it async and ensuring we either get OK or InvalidArgument
3532
+ restore_verify_threads[i] =
3533
+ std::thread([this, &db_opts, restore_db_dir, to_restore] {
3534
+ DB* restored;
3535
+ Status s;
3536
+ for (;;) {
3537
+ s = DB::Open(db_opts, restore_db_dir, &restored);
3538
+ if (s.IsInvalidArgument()) {
3539
+ // Restore hasn't finished
3540
+ test_db_env_->SleepForMicroseconds(1000);
3541
+ continue;
3542
+ } else {
3543
+ // We should only get InvalidArgument if restore is
3544
+ // incomplete, or OK if complete
3545
+ ASSERT_OK(s);
3546
+ break;
3547
+ }
3548
+ }
3549
+ int factor = std::min(static_cast<int>(to_restore), max_factor);
3550
+ AssertExists(restored, 0, factor * keys_iteration);
3551
+ AssertEmpty(restored, factor * keys_iteration,
3552
+ (factor + 1) * keys_iteration);
3553
+ delete restored;
3554
+ });
3555
+
3556
+ // (Ok now) Restore one of the backups, or "latest"
3557
+ if (latest) {
3558
+ ASSERT_OK(my_be->RestoreDBFromLatestBackup(restore_db_dir,
3559
+ restore_db_dir));
3560
+ } else {
3561
+ ASSERT_OK(my_be->VerifyBackup(to_restore, true));
3562
+ ASSERT_OK(my_be->RestoreDBFromBackup(to_restore, restore_db_dir,
3563
+ restore_db_dir));
3564
+ }
3565
+
3566
+ // Test for race condition in reconfiguring limiter
3567
+ // FIXME: this could set to a different value in all threads, except
3568
+ // GenericRateLimiter::SetBytesPerSecond has a write-write race
3569
+ // reported by TSAN
3570
+ if (i == 0) {
3571
+ limiter->SetBytesPerSecond(2000000000);
3572
+ }
3573
+
3574
+ // Re-verify metadata (we don't receive updates from concurrently
3575
+ // creating a new backup)
3576
+ my_be->GetBackupInfo(&infos);
3577
+ ASSERT_EQ(infos.size(), count);
3578
+ my_be->GetCorruptedBackups(&ids);
3579
+ ASSERT_EQ(ids.size(), 0);
3580
+ // fprintf(stderr, "Finished read thread\n");
3581
+
3582
+ if (reopen) {
3583
+ delete my_be;
3584
+ }
3585
+ });
3586
+ }
3587
+
3588
+ BackupEngine* alt_be;
3589
+ ASSERT_OK(BackupEngine::Open(test_db_env_.get(), be_opts, &alt_be));
3590
+
3591
+ std::array<std::thread, 2> append_threads;
3592
+ for (unsigned i = 0; i < append_threads.size(); ++i) {
3593
+ uint32_t sleep_micros = rng() % 100000;
3594
+ append_threads[i] = std::thread([this, sleep_micros, alt_be] {
3595
+ test_db_env_->SleepForMicroseconds(sleep_micros);
3596
+ // WART: CreateNewBackup doesn't tell you the BackupID it just created,
3597
+ // which is ugly for multithreaded setting.
3598
+ // TODO: add delete backup also when that is added
3599
+ ASSERT_OK(alt_be->CreateNewBackup(db_.get()));
3600
+ // fprintf(stderr, "Finished append thread\n");
3601
+ });
3602
+ }
3603
+
3604
+ for (auto& t : append_threads) {
3605
+ t.join();
3606
+ }
3607
+ // Verify metadata
3608
+ std::vector<BackupInfo> infos;
3609
+ alt_be->GetBackupInfo(&infos);
3610
+ ASSERT_EQ(infos.size(), 2 + append_threads.size());
3611
+
3612
+ for (auto& t : read_threads) {
3613
+ t.join();
3614
+ }
3615
+
3616
+ delete alt_be;
3617
+
3618
+ for (auto& t : restore_verify_threads) {
3619
+ t.join();
3620
+ }
3621
+
3622
+ CloseDBAndBackupEngine();
3623
+ }
3624
+
3625
+ TEST_F(BackupEngineTest, LimitBackupsOpened) {
2680
3626
  // Verify the specified max backups are opened, including skipping over
2681
3627
  // corrupted backups.
2682
3628
  //
@@ -2698,12 +3644,11 @@ TEST_F(BackupableDBTest, LimitBackupsOpened) {
2698
3644
  }
2699
3645
  CloseDBAndBackupEngine();
2700
3646
 
2701
- backupable_options_->max_valid_backups_to_open = 2;
2702
- backupable_options_->destroy_old_data = false;
3647
+ engine_options_->max_valid_backups_to_open = 2;
3648
+ engine_options_->destroy_old_data = false;
2703
3649
  BackupEngineReadOnly* read_only_backup_engine;
2704
- ASSERT_OK(BackupEngineReadOnly::Open(backup_chroot_env_.get(),
2705
- *backupable_options_,
2706
- &read_only_backup_engine));
3650
+ ASSERT_OK(BackupEngineReadOnly::Open(
3651
+ backup_chroot_env_.get(), *engine_options_, &read_only_backup_engine));
2707
3652
 
2708
3653
  std::vector<BackupInfo> backup_infos;
2709
3654
  read_only_backup_engine->GetBackupInfo(&backup_infos);
@@ -2713,7 +3658,7 @@ TEST_F(BackupableDBTest, LimitBackupsOpened) {
2713
3658
  delete read_only_backup_engine;
2714
3659
  }
2715
3660
 
2716
- TEST_F(BackupableDBTest, IgnoreLimitBackupsOpenedWhenNotReadOnly) {
3661
+ TEST_F(BackupEngineTest, IgnoreLimitBackupsOpenedWhenNotReadOnly) {
2717
3662
  // Verify the specified max_valid_backups_to_open is ignored if the engine
2718
3663
  // is not read-only.
2719
3664
  //
@@ -2735,7 +3680,7 @@ TEST_F(BackupableDBTest, IgnoreLimitBackupsOpenedWhenNotReadOnly) {
2735
3680
  }
2736
3681
  CloseDBAndBackupEngine();
2737
3682
 
2738
- backupable_options_->max_valid_backups_to_open = 2;
3683
+ engine_options_->max_valid_backups_to_open = 2;
2739
3684
  OpenDBAndBackupEngine();
2740
3685
  std::vector<BackupInfo> backup_infos;
2741
3686
  backup_engine_->GetBackupInfo(&backup_infos);
@@ -2747,11 +3692,13 @@ TEST_F(BackupableDBTest, IgnoreLimitBackupsOpenedWhenNotReadOnly) {
2747
3692
  DestroyDB(dbname_, options_);
2748
3693
  }
2749
3694
 
2750
- TEST_F(BackupableDBTest, CreateWhenLatestBackupCorrupted) {
3695
+ TEST_F(BackupEngineTest, CreateWhenLatestBackupCorrupted) {
2751
3696
  // we should pick an ID greater than corrupted backups' IDs so creation can
2752
3697
  // succeed even when latest backup is corrupted.
2753
3698
  const int kNumKeys = 5000;
2754
3699
  OpenDBAndBackupEngine(true /* destroy_old_data */);
3700
+ BackupInfo backup_info;
3701
+ ASSERT_TRUE(backup_engine_->GetLatestBackupInfo(&backup_info).IsNotFound());
2755
3702
  FillDB(db_.get(), 0 /* from */, kNumKeys);
2756
3703
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2757
3704
  true /* flush_before_backup */));
@@ -2760,15 +3707,29 @@ TEST_F(BackupableDBTest, CreateWhenLatestBackupCorrupted) {
2760
3707
  CloseDBAndBackupEngine();
2761
3708
 
2762
3709
  OpenDBAndBackupEngine();
3710
+ ASSERT_TRUE(backup_engine_->GetLatestBackupInfo(&backup_info).IsNotFound());
3711
+
2763
3712
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
2764
3713
  true /* flush_before_backup */));
3714
+
3715
+ ASSERT_TRUE(backup_engine_->GetLatestBackupInfo(&backup_info).ok());
3716
+ ASSERT_EQ(2, backup_info.backup_id);
3717
+
2765
3718
  std::vector<BackupInfo> backup_infos;
2766
3719
  backup_engine_->GetBackupInfo(&backup_infos);
2767
3720
  ASSERT_EQ(1, backup_infos.size());
2768
3721
  ASSERT_EQ(2, backup_infos[0].backup_id);
3722
+
3723
+ // Verify individual GetBackupInfo by ID
3724
+ ASSERT_TRUE(backup_engine_->GetBackupInfo(0U, &backup_info).IsNotFound());
3725
+ ASSERT_TRUE(backup_engine_->GetBackupInfo(1U, &backup_info).IsCorruption());
3726
+ ASSERT_TRUE(backup_engine_->GetBackupInfo(2U, &backup_info).ok());
3727
+ ASSERT_TRUE(backup_engine_->GetBackupInfo(3U, &backup_info).IsNotFound());
3728
+ ASSERT_TRUE(
3729
+ backup_engine_->GetBackupInfo(999999U, &backup_info).IsNotFound());
2769
3730
  }
2770
3731
 
2771
- TEST_F(BackupableDBTest, WriteOnlyEngineNoSharedFileDeletion) {
3732
+ TEST_F(BackupEngineTest, WriteOnlyEngineNoSharedFileDeletion) {
2772
3733
  // Verifies a write-only BackupEngine does not delete files belonging to valid
2773
3734
  // backups when GarbageCollect, PurgeOldBackups, or DeleteBackup are called.
2774
3735
  const int kNumKeys = 5000;
@@ -2778,7 +3739,7 @@ TEST_F(BackupableDBTest, WriteOnlyEngineNoSharedFileDeletion) {
2778
3739
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(), true));
2779
3740
  CloseDBAndBackupEngine();
2780
3741
 
2781
- backupable_options_->max_valid_backups_to_open = 0;
3742
+ engine_options_->max_valid_backups_to_open = 0;
2782
3743
  OpenDBAndBackupEngine();
2783
3744
  switch (i) {
2784
3745
  case 0:
@@ -2795,12 +3756,12 @@ TEST_F(BackupableDBTest, WriteOnlyEngineNoSharedFileDeletion) {
2795
3756
  }
2796
3757
  CloseDBAndBackupEngine();
2797
3758
 
2798
- backupable_options_->max_valid_backups_to_open = port::kMaxInt32;
3759
+ engine_options_->max_valid_backups_to_open = port::kMaxInt32;
2799
3760
  AssertBackupConsistency(i + 1, 0, (i + 1) * kNumKeys);
2800
3761
  }
2801
3762
  }
2802
3763
 
2803
- TEST_P(BackupableDBTestWithParam, BackupUsingDirectIO) {
3764
+ TEST_P(BackupEngineTestWithParam, BackupUsingDirectIO) {
2804
3765
  // Tests direct I/O on the backup engine's reads and writes on the DB env and
2805
3766
  // backup env
2806
3767
  // We use ChrootEnv underneath so the below line checks for direct I/O support
@@ -2819,8 +3780,8 @@ TEST_P(BackupableDBTestWithParam, BackupUsingDirectIO) {
2819
3780
 
2820
3781
  // Clear the file open counters and then do a bunch of backup engine ops.
2821
3782
  // For all ops, files should be opened in direct mode.
2822
- test_backup_env_->ClearFileOpenCounters();
2823
- test_db_env_->ClearFileOpenCounters();
3783
+ test_backup_fs_->ClearFileOpenCounters();
3784
+ test_db_fs_->ClearFileOpenCounters();
2824
3785
  CloseBackupEngine();
2825
3786
  OpenBackupEngine();
2826
3787
  ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
@@ -2833,15 +3794,15 @@ TEST_P(BackupableDBTestWithParam, BackupUsingDirectIO) {
2833
3794
  ASSERT_EQ(static_cast<size_t>(i + 1), backup_infos.size());
2834
3795
 
2835
3796
  // Verify backup engine always opened files with direct I/O
2836
- ASSERT_EQ(0, test_db_env_->num_writers());
2837
- ASSERT_GE(test_db_env_->num_direct_rand_readers(), 0);
2838
- ASSERT_GT(test_db_env_->num_direct_seq_readers(), 0);
3797
+ ASSERT_EQ(0, test_db_fs_->num_writers());
3798
+ ASSERT_GE(test_db_fs_->num_direct_rand_readers(), 0);
3799
+ ASSERT_GT(test_db_fs_->num_direct_seq_readers(), 0);
2839
3800
  // Currently the DB doesn't support reading WALs or manifest with direct
2840
3801
  // I/O, so subtract two.
2841
- ASSERT_EQ(test_db_env_->num_seq_readers() - 2,
2842
- test_db_env_->num_direct_seq_readers());
2843
- ASSERT_EQ(test_db_env_->num_rand_readers(),
2844
- test_db_env_->num_direct_rand_readers());
3802
+ ASSERT_EQ(test_db_fs_->num_seq_readers() - 2,
3803
+ test_db_fs_->num_direct_seq_readers());
3804
+ ASSERT_EQ(test_db_fs_->num_rand_readers(),
3805
+ test_db_fs_->num_direct_rand_readers());
2845
3806
  }
2846
3807
  CloseDBAndBackupEngine();
2847
3808
 
@@ -2853,7 +3814,7 @@ TEST_P(BackupableDBTestWithParam, BackupUsingDirectIO) {
2853
3814
  }
2854
3815
  }
2855
3816
 
2856
- TEST_F(BackupableDBTest, BackgroundThreadCpuPriority) {
3817
+ TEST_F(BackupEngineTest, BackgroundThreadCpuPriority) {
2857
3818
  std::atomic<CpuPriority> priority(CpuPriority::kNormal);
2858
3819
  ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
2859
3820
  "BackupEngineImpl::Initialize:SetCpuPriority", [&](void* new_priority) {
@@ -2863,7 +3824,7 @@ TEST_F(BackupableDBTest, BackgroundThreadCpuPriority) {
2863
3824
 
2864
3825
  // 1 thread is easier to test, otherwise, we may not be sure which thread
2865
3826
  // actually does the work during CreateNewBackup.
2866
- backupable_options_->max_background_operations = 1;
3827
+ engine_options_->max_background_operations = 1;
2867
3828
  OpenDBAndBackupEngine(true);
2868
3829
 
2869
3830
  {
@@ -2923,7 +3884,11 @@ TEST_F(BackupableDBTest, BackgroundThreadCpuPriority) {
2923
3884
  CreateBackupOptions options;
2924
3885
  options.decrease_background_thread_cpu_priority = true;
2925
3886
  options.background_thread_cpu_priority = CpuPriority::kIdle;
2926
- ASSERT_OK(backup_engine_->CreateNewBackup(options, db_.get()));
3887
+
3888
+ // Also check output backup_id with CreateNewBackup
3889
+ BackupID new_id = 0;
3890
+ ASSERT_OK(backup_engine_->CreateNewBackup(options, db_.get(), &new_id));
3891
+ ASSERT_EQ(new_id, 5U);
2927
3892
 
2928
3893
  ASSERT_EQ(priority, CpuPriority::kNormal);
2929
3894
  }
@@ -2934,6 +3899,235 @@ TEST_F(BackupableDBTest, BackgroundThreadCpuPriority) {
2934
3899
  DestroyDB(dbname_, options_);
2935
3900
  }
2936
3901
 
3902
+ // Populates `*total_size` with the size of all files under `backup_dir`.
3903
+ // We don't go through `BackupEngine` currently because it's hard to figure out
3904
+ // the metadata file size.
3905
+ Status GetSizeOfBackupFiles(FileSystem* backup_fs,
3906
+ const std::string& backup_dir, size_t* total_size) {
3907
+ *total_size = 0;
3908
+ std::vector<std::string> dir_stack = {backup_dir};
3909
+ Status s;
3910
+ while (s.ok() && !dir_stack.empty()) {
3911
+ std::string dir = std::move(dir_stack.back());
3912
+ dir_stack.pop_back();
3913
+ std::vector<std::string> children;
3914
+ s = backup_fs->GetChildren(dir, IOOptions(), &children, nullptr /* dbg */);
3915
+ for (size_t i = 0; s.ok() && i < children.size(); ++i) {
3916
+ std::string path = dir + "/" + children[i];
3917
+ bool is_dir;
3918
+ s = backup_fs->IsDirectory(path, IOOptions(), &is_dir, nullptr /* dbg */);
3919
+ uint64_t file_size = 0;
3920
+ if (s.ok()) {
3921
+ if (is_dir) {
3922
+ dir_stack.emplace_back(std::move(path));
3923
+ } else {
3924
+ s = backup_fs->GetFileSize(path, IOOptions(), &file_size,
3925
+ nullptr /* dbg */);
3926
+ }
3927
+ }
3928
+ if (s.ok()) {
3929
+ *total_size += file_size;
3930
+ }
3931
+ }
3932
+ }
3933
+ return s;
3934
+ }
3935
+
3936
+ TEST_F(BackupEngineTest, IOStats) {
3937
+ // Tests the `BACKUP_READ_BYTES` and `BACKUP_WRITE_BYTES` ticker stats have
3938
+ // the expected values according to the files in the backups.
3939
+
3940
+ // These ticker stats are expected to be populated regardless of `PerfLevel`
3941
+ // in user thread
3942
+ SetPerfLevel(kDisable);
3943
+
3944
+ options_.statistics = CreateDBStatistics();
3945
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
3946
+ kShareWithChecksum);
3947
+
3948
+ FillDB(db_.get(), 0 /* from */, 100 /* to */, kFlushMost);
3949
+
3950
+ ASSERT_EQ(0, options_.statistics->getTickerCount(BACKUP_READ_BYTES));
3951
+ ASSERT_EQ(0, options_.statistics->getTickerCount(BACKUP_WRITE_BYTES));
3952
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
3953
+ false /* flush_before_backup */));
3954
+
3955
+ size_t orig_backup_files_size;
3956
+ ASSERT_OK(GetSizeOfBackupFiles(test_backup_env_->GetFileSystem().get(),
3957
+ backupdir_, &orig_backup_files_size));
3958
+ size_t expected_bytes_written = orig_backup_files_size;
3959
+ ASSERT_EQ(expected_bytes_written,
3960
+ options_.statistics->getTickerCount(BACKUP_WRITE_BYTES));
3961
+ // Bytes read is more difficult to pin down since there are reads for many
3962
+ // purposes other than creating file, like `GetSortedWalFiles()` to find first
3963
+ // sequence number, or `CreateNewBackup()` thread to find SST file session ID.
3964
+ // So we loosely require there are at least as many reads as needed for
3965
+ // copying, but not as many as twice that.
3966
+ ASSERT_GE(options_.statistics->getTickerCount(BACKUP_READ_BYTES),
3967
+ expected_bytes_written);
3968
+ ASSERT_LT(expected_bytes_written,
3969
+ 2 * options_.statistics->getTickerCount(BACKUP_READ_BYTES));
3970
+
3971
+ FillDB(db_.get(), 100 /* from */, 200 /* to */, kFlushMost);
3972
+
3973
+ ASSERT_OK(options_.statistics->Reset());
3974
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get(),
3975
+ false /* flush_before_backup */));
3976
+ size_t final_backup_files_size;
3977
+ ASSERT_OK(GetSizeOfBackupFiles(test_backup_env_->GetFileSystem().get(),
3978
+ backupdir_, &final_backup_files_size));
3979
+ expected_bytes_written = final_backup_files_size - orig_backup_files_size;
3980
+ ASSERT_EQ(expected_bytes_written,
3981
+ options_.statistics->getTickerCount(BACKUP_WRITE_BYTES));
3982
+ // See above for why these bounds were chosen.
3983
+ ASSERT_GE(options_.statistics->getTickerCount(BACKUP_READ_BYTES),
3984
+ expected_bytes_written);
3985
+ ASSERT_LT(expected_bytes_written,
3986
+ 2 * options_.statistics->getTickerCount(BACKUP_READ_BYTES));
3987
+ }
3988
+
3989
+ TEST_F(BackupEngineTest, FileTemperatures) {
3990
+ CloseDBAndBackupEngine();
3991
+
3992
+ // Required for recording+restoring temperatures
3993
+ engine_options_->schema_version = 2;
3994
+
3995
+ // More file IO instrumentation
3996
+ auto my_db_fs = std::make_shared<FileTemperatureTestFS>(db_chroot_fs_);
3997
+ test_db_fs_ = std::make_shared<TestFs>(my_db_fs);
3998
+ SetEnvsFromFileSystems();
3999
+
4000
+ // Use temperatures
4001
+ options_.bottommost_temperature = Temperature::kWarm;
4002
+ options_.level0_file_num_compaction_trigger = 2;
4003
+
4004
+ OpenDBAndBackupEngine(true /* destroy_old_data */, false /* dummy */,
4005
+ kShareWithChecksum);
4006
+
4007
+ // generate a bottommost file (combined from 2) and a non-bottommost file
4008
+ DBImpl* dbi = static_cast_with_check<DBImpl>(db_.get());
4009
+ ASSERT_OK(db_->Put(WriteOptions(), "a", "val"));
4010
+ ASSERT_OK(db_->Put(WriteOptions(), "c", "val"));
4011
+ ASSERT_OK(db_->Flush(FlushOptions()));
4012
+ ASSERT_OK(db_->Put(WriteOptions(), "b", "val"));
4013
+ ASSERT_OK(db_->Put(WriteOptions(), "d", "val"));
4014
+ ASSERT_OK(db_->Flush(FlushOptions()));
4015
+ ASSERT_OK(dbi->TEST_WaitForCompact());
4016
+ ASSERT_OK(db_->Put(WriteOptions(), "e", "val"));
4017
+ ASSERT_OK(db_->Flush(FlushOptions()));
4018
+
4019
+ // Get temperatures from manifest
4020
+ std::map<uint64_t, Temperature> manifest_temps;
4021
+ std::map<Temperature, int> manifest_temp_counts;
4022
+ {
4023
+ std::vector<LiveFileStorageInfo> infos;
4024
+ ASSERT_OK(
4025
+ db_->GetLiveFilesStorageInfo(LiveFilesStorageInfoOptions(), &infos));
4026
+ for (auto info : infos) {
4027
+ if (info.file_type == kTableFile) {
4028
+ manifest_temps.emplace(info.file_number, info.temperature);
4029
+ manifest_temp_counts[info.temperature]++;
4030
+ }
4031
+ }
4032
+ }
4033
+
4034
+ // Verify expected manifest temperatures
4035
+ ASSERT_EQ(manifest_temp_counts.size(), 2);
4036
+ ASSERT_EQ(manifest_temp_counts[Temperature::kWarm], 1);
4037
+ ASSERT_EQ(manifest_temp_counts[Temperature::kUnknown], 1);
4038
+
4039
+ // Verify manifest temperatures match FS temperatures
4040
+ std::map<uint64_t, Temperature> current_temps;
4041
+ my_db_fs->CopyCurrentSstFileTemperatures(&current_temps);
4042
+ for (const auto& manifest_temp : manifest_temps) {
4043
+ ASSERT_EQ(current_temps[manifest_temp.first], manifest_temp.second);
4044
+ }
4045
+
4046
+ // Try a few different things
4047
+ for (int i = 1; i <= 5; ++i) {
4048
+ // Expected temperatures after restore are based on manifest temperatures
4049
+ std::map<uint64_t, Temperature> expected_temps = manifest_temps;
4050
+
4051
+ if (i >= 2) {
4052
+ // For iterations 2 & 3, override current temperature of one file
4053
+ // and vary which temperature is authoritative (current or manifest).
4054
+ // For iterations 4 & 5, override current temperature of both files
4055
+ // but make sure an current temperate always takes precedence over
4056
+ // unknown regardless of current_temperatures_override_manifest setting.
4057
+ bool use_current = ((i % 2) == 1);
4058
+ engine_options_->current_temperatures_override_manifest = use_current;
4059
+ CloseBackupEngine();
4060
+ OpenBackupEngine();
4061
+ for (const auto& manifest_temp : manifest_temps) {
4062
+ if (i <= 3) {
4063
+ if (manifest_temp.second == Temperature::kWarm) {
4064
+ my_db_fs->OverrideSstFileTemperature(manifest_temp.first,
4065
+ Temperature::kCold);
4066
+ if (use_current) {
4067
+ expected_temps[manifest_temp.first] = Temperature::kCold;
4068
+ }
4069
+ }
4070
+ } else {
4071
+ assert(i <= 5);
4072
+ if (manifest_temp.second == Temperature::kWarm) {
4073
+ my_db_fs->OverrideSstFileTemperature(manifest_temp.first,
4074
+ Temperature::kUnknown);
4075
+ } else {
4076
+ ASSERT_EQ(manifest_temp.second, Temperature::kUnknown);
4077
+ my_db_fs->OverrideSstFileTemperature(manifest_temp.first,
4078
+ Temperature::kHot);
4079
+ // regardless of use_current
4080
+ expected_temps[manifest_temp.first] = Temperature::kHot;
4081
+ }
4082
+ }
4083
+ }
4084
+ }
4085
+
4086
+ // Sample requested temperatures in opening files for backup
4087
+ my_db_fs->PopRequestedSstFileTemperatures();
4088
+ ASSERT_OK(backup_engine_->CreateNewBackup(db_.get()));
4089
+
4090
+ // Verify requested temperatures against manifest temperatures (before
4091
+ // backup finds out current temperatures in FileSystem)
4092
+ std::vector<std::pair<uint64_t, Temperature>> requested_temps;
4093
+ my_db_fs->PopRequestedSstFileTemperatures(&requested_temps);
4094
+ std::set<uint64_t> distinct_requests;
4095
+ for (const auto& requested_temp : requested_temps) {
4096
+ // Matching manifest temperatures
4097
+ ASSERT_EQ(manifest_temps.at(requested_temp.first), requested_temp.second);
4098
+ distinct_requests.insert(requested_temp.first);
4099
+ }
4100
+ // Two distinct requests
4101
+ ASSERT_EQ(distinct_requests.size(), 2);
4102
+
4103
+ // Verify against backup info file details API
4104
+ BackupInfo info;
4105
+ ASSERT_OK(backup_engine_->GetLatestBackupInfo(
4106
+ &info, /*include_file_details*/ true));
4107
+ ASSERT_GT(info.file_details.size(), 2);
4108
+ for (auto& e : info.file_details) {
4109
+ ASSERT_EQ(expected_temps[e.file_number], e.temperature);
4110
+ }
4111
+
4112
+ // Restore backup to another virtual (tiered) dir
4113
+ const std::string restore_dir = "/restore" + ToString(i);
4114
+ ASSERT_OK(backup_engine_->RestoreDBFromLatestBackup(
4115
+ RestoreOptions(), restore_dir, restore_dir));
4116
+
4117
+ // Verify restored FS temperatures match expectation
4118
+ // (FileTemperatureTestFS doesn't distinguish directories when reporting
4119
+ // current temperatures, just whatever SST was written or overridden last
4120
+ // with that file number.)
4121
+ my_db_fs->CopyCurrentSstFileTemperatures(&current_temps);
4122
+ for (const auto& expected_temp : expected_temps) {
4123
+ ASSERT_EQ(current_temps[expected_temp.first], expected_temp.second);
4124
+ }
4125
+
4126
+ // Delete backup to force next backup to copy files
4127
+ ASSERT_OK(backup_engine_->PurgeOldBackups(0));
4128
+ }
4129
+ }
4130
+
2937
4131
  } // anon namespace
2938
4132
 
2939
4133
  } // namespace ROCKSDB_NAMESPACE
@@ -2948,7 +4142,7 @@ int main(int argc, char** argv) {
2948
4142
  #include <stdio.h>
2949
4143
 
2950
4144
  int main(int /*argc*/, char** /*argv*/) {
2951
- fprintf(stderr, "SKIPPED as BackupableDB is not supported in ROCKSDB_LITE\n");
4145
+ fprintf(stderr, "SKIPPED as BackupEngine is not supported in ROCKSDB_LITE\n");
2952
4146
  return 0;
2953
4147
  }
2954
4148