1 /* 2 Copyright (c) 2015, Facebook, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; version 2 of the License. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program; if not, write to the Free Software 15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 16 #pragma once 17 18 /* C++ system header files */ 19 #include <map> 20 #include <memory> 21 #include <string> 22 #include <unordered_set> 23 #include <vector> 24 25 /* RocksDB header files */ 26 #include "rocksdb/db.h" 27 28 /* MyRocks header files */ 29 #include "./ha_rocksdb.h" 30 31 namespace myrocks { 32 33 class Rdb_ddl_manager; 34 class Rdb_key_def; 35 36 extern std::atomic<uint64_t> rocksdb_num_sst_entry_put; 37 extern std::atomic<uint64_t> rocksdb_num_sst_entry_delete; 38 extern std::atomic<uint64_t> rocksdb_num_sst_entry_singledelete; 39 extern std::atomic<uint64_t> rocksdb_num_sst_entry_merge; 40 extern std::atomic<uint64_t> rocksdb_num_sst_entry_other; 41 extern std::atomic<uint64_t> rocksdb_additional_compaction_triggers; 42 extern my_bool rocksdb_compaction_sequential_deletes_count_sd; 43 44 struct Rdb_compact_params { 45 uint64_t m_deletes, m_window, m_file_size; 46 }; 47 48 struct Rdb_index_stats { 49 enum { 50 INDEX_STATS_VERSION_INITIAL = 1, 51 INDEX_STATS_VERSION_ENTRY_TYPES = 2, 52 }; 53 GL_INDEX_ID m_gl_index_id; 54 int64_t m_data_size, m_rows, m_actual_disk_size; 55 int64_t m_entry_deletes, m_entry_single_deletes; 56 int64_t m_entry_merges, m_entry_others; 57 std::vector<int64_t> m_distinct_keys_per_prefix; 58 std::string m_name; // name is not persisted 59 60 static std::string materialize(const std::vector<Rdb_index_stats> &stats); 61 static int unmaterialize(const std::string &s, 62 std::vector<Rdb_index_stats> *const ret); 63 Rdb_index_statsRdb_index_stats64 Rdb_index_stats() : Rdb_index_stats({0, 0}) {} Rdb_index_statsRdb_index_stats65 explicit Rdb_index_stats(GL_INDEX_ID gl_index_id) 66 : m_gl_index_id(gl_index_id), 67 m_data_size(0), 68 m_rows(0), 69 m_actual_disk_size(0), 70 m_entry_deletes(0), 71 m_entry_single_deletes(0), 72 m_entry_merges(0), 73 m_entry_others(0) {} 74 75 void merge(const Rdb_index_stats &s, const bool increment = true, 76 const int64_t estimated_data_len = 0); 77 78 void adjust_cardinality(double adjustment_factor); 79 80 void reset_cardinality(); 81 }; 82 83 struct Rdb_table_stats { 84 // TODO: With TTL rows can be removed without a decrement in 85 // m_stat_n_rows. We should take TTL into consideration later. 86 uint64 m_stat_n_rows; 87 uint64 m_stat_modified_counter; 88 time_t m_last_recalc; 89 Rdb_table_statsRdb_table_stats90 Rdb_table_stats() 91 : m_stat_n_rows(0), m_stat_modified_counter(0), m_last_recalc(0) {} 92 Rdb_table_statsRdb_table_stats93 explicit Rdb_table_stats(uint64 rows, uint64 modified_counter, 94 time_t last_recalc) 95 : m_stat_n_rows(rows), 96 m_stat_modified_counter(modified_counter), 97 m_last_recalc(last_recalc) {} 98 setRdb_table_stats99 void set(uint64 rows, uint64 modified_counter, time_t last_recalc) { 100 m_stat_n_rows = rows; 101 m_stat_modified_counter = modified_counter; 102 m_last_recalc = last_recalc; 103 } 104 }; 105 106 // The helper class to calculate index cardinality 107 class Rdb_tbl_card_coll { 108 public: 109 explicit Rdb_tbl_card_coll(const uint8_t table_stats_sampling_pct); 110 111 public: 112 void ProcessKey(const rocksdb::Slice &key, const Rdb_key_def *keydef, 113 Rdb_index_stats *stats); 114 /* 115 * Resets the state of the collector to start calculating statistics for a 116 * next index. 117 */ 118 void Reset(); 119 120 /* 121 * Cardinality statistics might be calculated using some sampling strategy. 122 * This method adjusts gathered statistics according to the sampling 123 * strategy used. Note that adjusted cardinality value is just an estimate 124 * and can return a value exeeding number of rows in a table, so the 125 * returned value should be capped by row count before using it by 126 * an optrimizer or displaying it to a clent. 127 */ 128 void AdjustStats(Rdb_index_stats *stats); 129 void SetCardinality(Rdb_index_stats *stat); 130 131 private: 132 bool ShouldCollectStats(); 133 bool IsSamplingDisabled() const; 134 135 private: 136 std::string m_last_key; 137 uint8_t m_table_stats_sampling_pct; 138 unsigned int m_seed; 139 }; 140 141 class Rdb_tbl_prop_coll : public rocksdb::TablePropertiesCollector { 142 public: 143 Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager, 144 const Rdb_compact_params ¶ms, const uint32_t cf_id, 145 const uint8_t table_stats_sampling_pct); 146 147 /* 148 Override parent class's virtual methods of interest. 149 */ 150 151 virtual rocksdb::Status AddUserKey(const rocksdb::Slice &key, 152 const rocksdb::Slice &value, 153 rocksdb::EntryType type, 154 rocksdb::SequenceNumber seq, 155 uint64_t file_size) override; 156 157 virtual rocksdb::Status Finish( 158 rocksdb::UserCollectedProperties *properties) override; 159 Name()160 virtual const char *Name() const override { return "Rdb_tbl_prop_coll"; } 161 162 rocksdb::UserCollectedProperties GetReadableProperties() const override; 163 164 bool NeedCompact() const override; 165 166 public: GetMaxDeletedRows()167 uint64_t GetMaxDeletedRows() const { return m_max_deleted_rows; } 168 169 static void read_stats_from_tbl_props( 170 const std::shared_ptr<const rocksdb::TableProperties> &table_props, 171 std::vector<Rdb_index_stats> *out_stats_vector); 172 173 private: 174 static std::string GetReadableStats(const Rdb_index_stats &it); 175 bool FilledWithDeletions() const; 176 bool ShouldCollectStats(); 177 void CollectStatsForRow(const rocksdb::Slice &key, 178 const rocksdb::Slice &value, 179 const rocksdb::EntryType &type, 180 const uint64_t file_size); 181 Rdb_index_stats *AccessStats(const rocksdb::Slice &key); 182 void AdjustDeletedRows(rocksdb::EntryType type); 183 184 private: 185 uint32_t m_cf_id; 186 std::shared_ptr<const Rdb_key_def> m_keydef; 187 Rdb_ddl_manager *m_ddl_manager; 188 std::vector<Rdb_index_stats> m_stats; 189 Rdb_index_stats *m_last_stats; 190 static const char *INDEXSTATS_KEY; 191 192 // last added key 193 std::string m_last_key; 194 195 // floating window to count deleted rows 196 std::vector<bool> m_deleted_rows_window; 197 uint64_t m_window_pos, m_deleted_rows, m_max_deleted_rows; 198 uint64_t m_total_puts, m_total_merges; 199 uint64_t m_total_deletes, m_total_singledeletes, m_total_others; 200 uint64_t m_file_size; 201 Rdb_compact_params m_params; 202 Rdb_tbl_card_coll m_cardinality_collector; 203 bool m_recorded; 204 }; 205 206 class Rdb_tbl_prop_coll_factory 207 : public rocksdb::TablePropertiesCollectorFactory { 208 public: 209 Rdb_tbl_prop_coll_factory(const Rdb_tbl_prop_coll_factory &) = delete; 210 Rdb_tbl_prop_coll_factory &operator=(const Rdb_tbl_prop_coll_factory &) = 211 delete; 212 Rdb_tbl_prop_coll_factory(Rdb_ddl_manager * ddl_manager)213 explicit Rdb_tbl_prop_coll_factory(Rdb_ddl_manager *ddl_manager) 214 : m_ddl_manager(ddl_manager) {} 215 216 /* 217 Override parent class's virtual methods of interest. 218 */ 219 CreateTablePropertiesCollector(rocksdb::TablePropertiesCollectorFactory::Context context)220 virtual rocksdb::TablePropertiesCollector *CreateTablePropertiesCollector( 221 rocksdb::TablePropertiesCollectorFactory::Context context) override { 222 return new Rdb_tbl_prop_coll(m_ddl_manager, m_params, 223 context.column_family_id, 224 m_table_stats_sampling_pct); 225 } 226 Name()227 virtual const char *Name() const override { 228 return "Rdb_tbl_prop_coll_factory"; 229 } 230 231 public: SetCompactionParams(const Rdb_compact_params & params)232 void SetCompactionParams(const Rdb_compact_params ¶ms) { 233 m_params = params; 234 } 235 SetTableStatsSamplingPct(const uint8_t table_stats_sampling_pct)236 void SetTableStatsSamplingPct(const uint8_t table_stats_sampling_pct) { 237 m_table_stats_sampling_pct = table_stats_sampling_pct; 238 } 239 240 private: 241 Rdb_ddl_manager *const m_ddl_manager; 242 Rdb_compact_params m_params; 243 uint8_t m_table_stats_sampling_pct; 244 }; 245 246 } // namespace myrocks 247