179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2016 MariaDB Corporation Ab
 | |
|  *
 | |
|  * Use of this software is governed by the Business Source License included
 | |
|  * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
 | |
|  *
 | |
|  * Change Date: 2025-10-29
 | |
|  *
 | |
|  * On the date above, in accordance with the Business Source License, use
 | |
|  * of this software will be governed by version 2 or later of the General
 | |
|  * Public License.
 | |
|  */
 | |
| 
 | |
| #define MXS_MODULE_NAME "csmon"
 | |
| 
 | |
| #include "csmon.hh"
 | |
| 
 | |
| #include <regex>
 | |
| #include <vector>
 | |
| #include <string>
 | |
| 
 | |
| #include <maxscale/modinfo.h>
 | |
| #include <maxscale/mysql_utils.hh>
 | |
| 
 | |
| using maxscale::MonitorServer;
 | |
| 
 | |
| namespace
 | |
| {
 | |
| 
 | |
| constexpr const char* alive_query = "SELECT mcsSystemReady() = 1 && mcsSystemReadOnly() <> 2";
 | |
| constexpr const char* role_query = "SELECT mcsSystemPrimary()";
 | |
| 
 | |
| // Helper for extracting string results from queries
 | |
| static std::string do_query(MonitorServer* srv, const char* query)
 | |
| {
 | |
|     std::string rval;
 | |
|     MYSQL_RES* result;
 | |
| 
 | |
|     if (mxs_mysql_query(srv->con, query) == 0 && (result = mysql_store_result(srv->con)))
 | |
|     {
 | |
|         MYSQL_ROW row = mysql_fetch_row(result);
 | |
| 
 | |
|         if (row && row[0])
 | |
|         {
 | |
|             rval = row[0];
 | |
|         }
 | |
| 
 | |
|         mysql_free_result(result);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         srv->mon_report_query_error();
 | |
|     }
 | |
| 
 | |
|     return rval;
 | |
| }
 | |
| 
 | |
| // Returns a numeric version similar to mysql_get_server_version
 | |
| int get_cs_version(MonitorServer* srv)
 | |
| {
 | |
|     int rval = -1;
 | |
|     std::string prefix = "Columnstore ";
 | |
|     std::string result = do_query(srv, "SELECT @@version_comment");
 | |
|     auto pos = result.find(prefix);
 | |
| 
 | |
|     auto to_version = [](std::string str) {
 | |
|             std::istringstream os(str);
 | |
|             int major = 0, minor = 0, patch = 0;
 | |
|             char dot;
 | |
|             os >> major;
 | |
|             os >> dot;
 | |
|             os >> minor;
 | |
|             os >> dot;
 | |
|             os >> patch;
 | |
|             return major * 10000 + minor * 100 + patch;
 | |
|         };
 | |
| 
 | |
|     if (pos != std::string::npos)
 | |
|     {
 | |
|         rval = to_version(result.substr(pos + prefix.length()));
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         auto cs_version = do_query(srv, "SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS "
 | |
|                                         "WHERE VARIABLE_NAME = 'Columnstore_version'");
 | |
| 
 | |
|         if (!cs_version.empty())
 | |
|         {
 | |
|             rval = to_version(cs_version);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return rval;
 | |
| }
 | |
| }
 | |
| 
 | |
| CsMonitor::CsMonitor(const std::string& name, const std::string& module)
 | |
|     : MonitorWorkerSimple(name, module)
 | |
| {
 | |
| }
 | |
| 
 | |
| CsMonitor::~CsMonitor()
 | |
| {
 | |
| }
 | |
| 
 | |
| // static
 | |
| CsMonitor* CsMonitor::create(const std::string& name, const std::string& module)
 | |
| {
 | |
|     return new CsMonitor(name, module);
 | |
| }
 | |
| 
 | |
| bool CsMonitor::has_sufficient_permissions()
 | |
| {
 | |
|     return test_permissions(alive_query);
 | |
| }
 | |
| 
 | |
| void CsMonitor::update_server_status(MonitorServer* srv)
 | |
| {
 | |
|     srv->clear_pending_status(SERVER_MASTER | SERVER_SLAVE | SERVER_RUNNING);
 | |
|     int status = 0;
 | |
| 
 | |
|     if (do_query(srv, alive_query) == "1")
 | |
|     {
 | |
|         auto version = get_cs_version(srv);
 | |
| 
 | |
|         if (version >= 0)
 | |
|         {
 | |
|             status |= SERVER_RUNNING;
 | |
| 
 | |
|             if (version >= 10200)
 | |
|             {
 | |
|                 // 1.2 supports the mcsSystemPrimary function
 | |
|                 status |= do_query(srv, role_query) == "1" ? SERVER_MASTER : SERVER_SLAVE;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 status |= srv->server == m_primary ? SERVER_MASTER : SERVER_SLAVE;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     srv->set_pending_status(status);
 | |
| }
 | |
| 
 | |
| bool CsMonitor::configure(const MXS_CONFIG_PARAMETER* pParams)
 | |
| {
 | |
|     if (!MonitorWorkerSimple::configure(pParams))
 | |
|     {
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     m_primary = pParams->get_server("primary");
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| extern "C" MXS_MODULE* MXS_CREATE_MODULE()
 | |
| {
 | |
|     static MXS_MODULE info =
 | |
|     {
 | |
|         MXS_MODULE_API_MONITOR,
 | |
|         MXS_MODULE_BETA_RELEASE,
 | |
|         MXS_MONITOR_VERSION,
 | |
|         "MariaDB ColumnStore monitor",
 | |
|         "V1.0.0",
 | |
|         MXS_NO_MODULE_CAPABILITIES,
 | |
|         &maxscale::MonitorApi<CsMonitor>::s_api,
 | |
|         NULL,                                   /* Process init. */
 | |
|         NULL,                                   /* Process finish. */
 | |
|         NULL,                                   /* Thread init. */
 | |
|         NULL,                                   /* Thread finish. */
 | |
|         {
 | |
|             {"primary",                         MXS_MODULE_PARAM_SERVER},
 | |
|             {MXS_END_MODULE_PARAMS}
 | |
|         }
 | |
|     };
 | |
| 
 | |
|     return &info;
 | |
| }
 | 
