]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd/OSDMap: health alert for non-power-of-two pg_num
authorSage Weil <sage@redhat.com>
Mon, 23 Sep 2019 19:40:48 +0000 (14:40 -0500)
committerSage Weil <sage@redhat.com>
Tue, 24 Sep 2019 14:26:33 +0000 (09:26 -0500)
Fixes: https://tracker.ceph.com/issues/41647
Signed-off-by: Sage Weil <sage@redhat.com>
PendingReleaseNotes
doc/rados/operations/health-checks.rst
src/common/options.cc
src/mon/OSDMonitor.cc
src/osd/OSDMap.cc
src/osd/OSDMap.h
src/tools/osdmaptool.cc

index 41a8886cc6340534aa7675d1d0fc215bc03c51f8..0f305adadac03b536fbb3e559c3ceb3d6e535554 100644 (file)
 * New OSD daemon command dump_scrub_reservations which reveals the
   scrub reservations that are held for local (primary) and remote (replica) PGs.
 
+* Ceph will now issue a health warning if a RADOS pool as a ``pg_num``
+  value that is not a power of two.  This can be fixed by adjusting
+  the pool to a nearby power of two::
+
+    ceph osd pool set <pool-name> pg_num <new-pg-num>
+
+  Alternatively, the warning can be silenced with::
+
+    ceph config set global mon_warn_on_pool_pg_num_not_power_of_two false
+
 * The ``pg_autoscale_mode`` is now set to ``on`` by default for newly
   created pools, which means that Ceph will automatically manage the
   number of PGs.  To change this behavior, or to learn more about PG
index 0068dc4a5858c5c1224c5390b0ed21c3b95ddbba..2536cd4f24d9b41944182748446086ee40011772 100644 (file)
@@ -740,6 +740,23 @@ The PG count for existing pools can be increased or new pools can be created.
 Please refer to :ref:`choosing-number-of-placement-groups` for more
 information.
 
+POOL_PG_NUM_NOT_POWER_OF_TWO
+____________________________
+
+One or more pools has a ``pg_num`` value that is not a power of two.
+Although this is not strictly incorrect, it does lead to a less
+balanced distribution of data because some PGs have roughly twice as
+much data as others.
+
+This is easily corrected by setting the ``pg_num`` value for the
+affected pool(s) to a nearby power of two::
+
+  ceph osd pool set <pool-name> pg_num <value>
+
+This health warning can be disabled with::
+
+  ceph config set global mon_warn_on_pool_pg_num_not_power_of_two false
+
 POOL_TOO_FEW_PGS
 ________________
 
index 0ebbe4b3037cdb016196c7d162974b4bce830255..f60182b5fa539a5402e72b55f9f72219d7534dae 100644 (file)
@@ -1702,6 +1702,11 @@ std::vector<Option> get_global_options() {
     .add_service("mgr")
     .set_description("issue POOL_APP_NOT_ENABLED health warning if pool has not application enabled"),
 
+    Option("mon_warn_on_pool_pg_num_not_power_of_two", Option::TYPE_BOOL, Option::LEVEL_DEV)
+    .set_default(true)
+    .add_service("mon")
+    .set_description("issue POOL_PG_NUM_NOT_POWER_OF_TWO warning if pool has a non-power-of-two pg_num value"),
+
     Option("mon_warn_on_misplaced", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
     .set_default(false)
     .add_service("mgr")
index 9b08b0bba7b43dfb470dc04c1acf92d4f1443901..be6894bd003260b54be8c6353ae7c335927cc8d0 100644 (file)
@@ -2014,7 +2014,7 @@ void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t)
 
   // health
   health_check_map_t next;
-  tmp.check_health(&next);
+  tmp.check_health(g_ceph_context, &next);
   encode_health(next, t);
 }
 
index 4e0b7adc60997125f3ee986f4bc2698fbff3be56..36444b172f53f2c641f74821bd1671f25e78fdc4 100644 (file)
@@ -5472,7 +5472,8 @@ void print_osd_utilization(const OSDMap& osdmap,
   }
 }
 
-void OSDMap::check_health(health_check_map_t *checks) const
+void OSDMap::check_health(CephContext *cct,
+                         health_check_map_t *checks) const
 {
   int num_osds = get_num_osds();
 
@@ -5904,6 +5905,27 @@ void OSDMap::check_health(health_check_map_t *checks) const
       d.detail.swap(nearfull_detail);
     }
   }
+
+  // POOL_PG_NUM_NOT_POWER_OF_TWO
+  if (cct->_conf.get_val<bool>("mon_warn_on_pool_pg_num_not_power_of_two")) {
+    list<string> detail;
+    for (auto it : get_pools()) {
+      if (!isp2(it.second.get_pg_num_target())) {
+       ostringstream ss;
+       ss << "pool '" << get_pool_name(it.first)
+          << "' pg_num " << it.second.get_pg_num_target()
+          << " is not a power of two";
+       detail.push_back(ss.str());
+      }
+    }
+    if (!detail.empty()) {
+      ostringstream ss;
+      ss << detail.size() << " pool(s) have non-power-of-two pg_num";
+      auto& d = checks->add("POOL_PG_NUM_NOT_POWER_OF_TWO", HEALTH_WARN,
+                           ss.str(), detail.size());
+      d.detail.swap(detail);
+    }
+  }
 }
 
 int OSDMap::parse_osd_id_list(const vector<string>& ls, set<int> *out,
index 5888f5dd4b32409c81599043012b4299076872e1..f0055611b2731b270bb84a6cd6435a8c82d6ea67 100644 (file)
@@ -1546,7 +1546,7 @@ public:
   static void generate_test_instances(std::list<OSDMap*>& o);
   bool check_new_blacklist_entries() const { return new_blacklist_entries; }
 
-  void check_health(health_check_map_t *checks) const;
+  void check_health(CephContext *cct, health_check_map_t *checks) const;
 
   int parse_osd_id_list(const std::vector<std::string>& ls,
                        std::set<int> *out,
index 1299d342939d0380f5558044e5435791d3406008..eed36e4e6a3517a5e68285c0f41af793d3b463fb 100644 (file)
@@ -659,7 +659,7 @@ int main(int argc, const char **argv)
 
   if (health) {
     health_check_map_t checks;
-    osdmap.check_health(&checks);
+    osdmap.check_health(g_ceph_context, &checks);
     JSONFormatter jf(true);
     jf.dump_object("checks", checks);
     jf.flush(cout);