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 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                                  const float card_adj_extra);
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), m_data_size(0), m_rows(0),
67         m_actual_disk_size(0), m_entry_deletes(0), m_entry_single_deletes(0),
68         m_entry_merges(0), m_entry_others(0) {}
69 
70   void merge(const Rdb_index_stats &s, const bool &increment = true,
71              const int64_t &estimated_data_len = 0);
72 };
73 
74 class Rdb_tbl_prop_coll : public rocksdb::TablePropertiesCollector {
75 public:
76   Rdb_tbl_prop_coll(Rdb_ddl_manager *const ddl_manager,
77                     const Rdb_compact_params &params, const uint32_t &cf_id,
78                     const uint8_t &table_stats_sampling_pct);
79 
80   /*
81     Override parent class's virtual methods of interest.
82   */
83 
84   virtual rocksdb::Status AddUserKey(const rocksdb::Slice &key,
85                                      const rocksdb::Slice &value,
86                                      rocksdb::EntryType type,
87                                      rocksdb::SequenceNumber seq,
88                                      uint64_t file_size);
89 
90   virtual rocksdb::Status
91   Finish(rocksdb::UserCollectedProperties *properties) override;
92 
Name()93   virtual const char *Name() const override { return "Rdb_tbl_prop_coll"; }
94 
95   rocksdb::UserCollectedProperties GetReadableProperties() const override;
96 
97   bool NeedCompact() const override;
98 
99 public:
GetMaxDeletedRows()100   uint64_t GetMaxDeletedRows() const { return m_max_deleted_rows; }
101 
102   static void read_stats_from_tbl_props(
103       const std::shared_ptr<const rocksdb::TableProperties> &table_props,
104       std::vector<Rdb_index_stats> *out_stats_vector);
105 
106 private:
107   static std::string GetReadableStats(const Rdb_index_stats &it);
108 
109   bool ShouldCollectStats();
110   void CollectStatsForRow(const rocksdb::Slice &key,
111                           const rocksdb::Slice &value,
112                           const rocksdb::EntryType &type,
113                           const uint64_t &file_size);
114   Rdb_index_stats *AccessStats(const rocksdb::Slice &key);
115   void AdjustDeletedRows(rocksdb::EntryType type);
116 
117 private:
118   uint32_t m_cf_id;
119   std::shared_ptr<const Rdb_key_def> m_keydef;
120   Rdb_ddl_manager *m_ddl_manager;
121   std::vector<Rdb_index_stats> m_stats;
122   Rdb_index_stats *m_last_stats;
123   static const char *INDEXSTATS_KEY;
124 
125   // last added key
126   std::string m_last_key;
127 
128   // floating window to count deleted rows
129   std::vector<bool> m_deleted_rows_window;
130   uint64_t m_rows, m_window_pos, m_deleted_rows, m_max_deleted_rows;
131   uint64_t m_file_size;
132   Rdb_compact_params m_params;
133   uint8_t m_table_stats_sampling_pct;
134   unsigned int m_seed;
135   float m_card_adj_extra;
136 };
137 
138 class Rdb_tbl_prop_coll_factory
139     : public rocksdb::TablePropertiesCollectorFactory {
140 public:
141   Rdb_tbl_prop_coll_factory(const Rdb_tbl_prop_coll_factory &) = delete;
142   Rdb_tbl_prop_coll_factory &
143   operator=(const Rdb_tbl_prop_coll_factory &) = delete;
144 
Rdb_tbl_prop_coll_factory(Rdb_ddl_manager * ddl_manager)145   explicit Rdb_tbl_prop_coll_factory(Rdb_ddl_manager *ddl_manager)
146       : m_ddl_manager(ddl_manager) {}
147 
148   /*
149     Override parent class's virtual methods of interest.
150   */
151 
CreateTablePropertiesCollector(rocksdb::TablePropertiesCollectorFactory::Context context)152   virtual rocksdb::TablePropertiesCollector *CreateTablePropertiesCollector(
153       rocksdb::TablePropertiesCollectorFactory::Context context) override {
154     return new Rdb_tbl_prop_coll(m_ddl_manager, m_params,
155                                  context.column_family_id,
156                                  m_table_stats_sampling_pct);
157   }
158 
Name()159   virtual const char *Name() const override {
160     return "Rdb_tbl_prop_coll_factory";
161   }
162 
163 public:
SetCompactionParams(const Rdb_compact_params & params)164   void SetCompactionParams(const Rdb_compact_params &params) {
165     m_params = params;
166   }
167 
SetTableStatsSamplingPct(const uint8_t & table_stats_sampling_pct)168   void SetTableStatsSamplingPct(const uint8_t &table_stats_sampling_pct) {
169     m_table_stats_sampling_pct = table_stats_sampling_pct;
170   }
171 
172 private:
173   Rdb_ddl_manager *const m_ddl_manager;
174   Rdb_compact_params m_params;
175   uint8_t m_table_stats_sampling_pct;
176 };
177 
178 } // namespace myrocks
179