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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 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 my_bool rocksdb_compaction_sequential_deletes_count_sd; 42 43 struct Rdb_compact_params { 44 uint64_t m_deletes, m_window, m_file_size; 45 }; 46 47 struct Rdb_index_stats { 48 enum { 49 INDEX_STATS_VERSION_INITIAL = 1, 50 INDEX_STATS_VERSION_ENTRY_TYPES = 2, 51 }; 52 GL_INDEX_ID m_gl_index_id; 53 int64_t m_data_size, m_rows, m_actual_disk_size; 54 int64_t m_entry_deletes, m_entry_single_deletes; 55 int64_t m_entry_merges, m_entry_others; 56 std::vector<int64_t> m_distinct_keys_per_prefix; 57 std::string m_name; // name is not persisted 58 59 static std::string materialize(const std::vector<Rdb_index_stats> &stats); 60 static int unmaterialize(const std::string &s, 61 std::vector<Rdb_index_stats> *const ret); 62 63 Rdb_index_stats() : Rdb_index_stats({0, 0}) {} 64 explicit Rdb_index_stats(GL_INDEX_ID gl_index_id) 65 : m_gl_index_id(gl_index_id), 66 m_data_size(0), 67 m_rows(0), 68 m_actual_disk_size(0), 69 m_entry_deletes(0), 70 m_entry_single_deletes(0), 71 m_entry_merges(0), 72 m_entry_others(0) {} 73 74 void merge(const Rdb_index_stats &s, const bool increment = true, 75 const int64_t estimated_data_len = 0); 76 }; 77 78 // The helper class to calculate index cardinality 79 class Rdb_tbl_card_coll { 80 public: 81 explicit Rdb_tbl_card_coll(const uint8_t table_stats_sampling_pct); 82 83 public: 84 void ProcessKey(const rocksdb::Slice &key, const Rdb_key_def *keydef, 85 Rdb_index_stats *stats); 86 /* 87 * Resets the state of the collector to start calculating statistics for a 88 * next index. 89 */ 90 void Reset(); 91 92 /* 93 * Cardinality statistics might be calculated using some sampling strategy. 94 * This method adjusts gathered statistics according to the sampling 95 * strategy used. Note that adjusted cardinality value is just an estimate 96 * and can return a value exeeding number of rows in a table, so the 97 * returned value should be capped by row count before using it by 98 * an optrimizer or displaying it to a clent. 99 */ 100 void AdjustStats(Rdb_index_stats *stats); 101 102 private: 103 bool ShouldCollectStats(); 104 bool IsSampingDisabled(); 105 106 private: 107 std::string m_last_key; 108 uint8_t m_table_stats_sampling_pct; 109 unsigned int m_seed; 110 }; 111 112 class Rdb_tbl_prop_coll : public rocksdb::TablePropertiesCollector { 113 public: 114 Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager, 115 const Rdb_compact_params ¶ms, const uint32_t cf_id, 116 const uint8_t table_stats_sampling_pct); 117 118 /* 119 Override parent class's virtual methods of interest. 120 */ 121 122 virtual rocksdb::Status AddUserKey(const rocksdb::Slice &key, 123 const rocksdb::Slice &value, 124 rocksdb::EntryType type, 125 rocksdb::SequenceNumber seq, 126 uint64_t file_size) override; 127 128 virtual rocksdb::Status Finish( 129 rocksdb::UserCollectedProperties *properties) override; 130 131 virtual const char *Name() const override { return "Rdb_tbl_prop_coll"; } 132 133 rocksdb::UserCollectedProperties GetReadableProperties() const override; 134 135 bool NeedCompact() const override; 136 137 public: 138 uint64_t GetMaxDeletedRows() const { return m_max_deleted_rows; } 139 140 static void read_stats_from_tbl_props( 141 const std::shared_ptr<const rocksdb::TableProperties> &table_props, 142 std::vector<Rdb_index_stats> *out_stats_vector); 143 144 private: 145 static std::string GetReadableStats(const Rdb_index_stats &it); 146 147 bool ShouldCollectStats(); 148 void CollectStatsForRow(const rocksdb::Slice &key, 149 const rocksdb::Slice &value, 150 const rocksdb::EntryType &type, 151 const uint64_t file_size); 152 Rdb_index_stats *AccessStats(const rocksdb::Slice &key); 153 void AdjustDeletedRows(rocksdb::EntryType type); 154 155 private: 156 uint32_t m_cf_id; 157 std::shared_ptr<const Rdb_key_def> m_keydef; 158 Rdb_ddl_manager *m_ddl_manager; 159 std::vector<Rdb_index_stats> m_stats; 160 Rdb_index_stats *m_last_stats; 161 static const char *INDEXSTATS_KEY; 162 163 // last added key 164 std::string m_last_key; 165 166 // floating window to count deleted rows 167 std::vector<bool> m_deleted_rows_window; 168 uint64_t m_rows, m_window_pos, m_deleted_rows, m_max_deleted_rows; 169 uint64_t m_file_size; 170 Rdb_compact_params m_params; 171 Rdb_tbl_card_coll m_cardinality_collector; 172 bool m_recorded; 173 }; 174 175 class Rdb_tbl_prop_coll_factory 176 : public rocksdb::TablePropertiesCollectorFactory { 177 public: 178 Rdb_tbl_prop_coll_factory(const Rdb_tbl_prop_coll_factory &) = delete; 179 Rdb_tbl_prop_coll_factory &operator=(const Rdb_tbl_prop_coll_factory &) = 180 delete; 181 182 explicit Rdb_tbl_prop_coll_factory(Rdb_ddl_manager *ddl_manager) 183 : m_ddl_manager(ddl_manager) {} 184 185 /* 186 Override parent class's virtual methods of interest. 187 */ 188 189 virtual rocksdb::TablePropertiesCollector *CreateTablePropertiesCollector( 190 rocksdb::TablePropertiesCollectorFactory::Context context) override { 191 return new Rdb_tbl_prop_coll(m_ddl_manager, m_params, 192 context.column_family_id, 193 m_table_stats_sampling_pct); 194 } 195 196 virtual const char *Name() const override { 197 return "Rdb_tbl_prop_coll_factory"; 198 } 199 200 public: 201 void SetCompactionParams(const Rdb_compact_params ¶ms) { 202 m_params = params; 203 } 204 205 void SetTableStatsSamplingPct(const uint8_t table_stats_sampling_pct) { 206 m_table_stats_sampling_pct = table_stats_sampling_pct; 207 } 208 209 private: 210 Rdb_ddl_manager *const m_ddl_manager; 211 Rdb_compact_params m_params; 212 uint8_t m_table_stats_sampling_pct; 213 }; 214 215 } // namespace myrocks 216