From 2a91443f12fa013263fd4d29c821b71da6336c79 Mon Sep 17 00:00:00 2001 From: root <root@rivolta.investici.org> Date: Sun, 6 Mar 2011 00:41:33 +0000 Subject: [PATCH] switch to new hashing algorithm for hyperdb --- db-config-old.php | 300 +++++++++++++++++++++++ db-config.php | 306 +----------------------- r2db/README | 15 ++ r2db/db-backends.php | 35 +++ db-hash.php => r2db/db-hash.php | 0 flexihash.php => r2db/flexihash.php | 0 r2db/tools/db-migrate-to-new-schema.php | 94 ++++++++ 7 files changed, 457 insertions(+), 293 deletions(-) create mode 100644 db-config-old.php create mode 100644 r2db/README create mode 100644 r2db/db-backends.php rename db-hash.php => r2db/db-hash.php (100%) rename flexihash.php => r2db/flexihash.php (100%) create mode 100755 r2db/tools/db-migrate-to-new-schema.php diff --git a/db-config-old.php b/db-config-old.php new file mode 100644 index 000000000..ca3793e19 --- /dev/null +++ b/db-config-old.php @@ -0,0 +1,300 @@ +<?php + +/** + * HyperDB configuration file + * + * This file should be installed at ABSPATH/db-config.php + * + * $wpdb is an instance of the hyperdb class which extends the wpdb class. + * + * See readme.txt for documentation. + */ + +/** + * Introduction to HyperDB configuration + * + * HyperDB can manage connections to a large number of databases. Queries are + * distributed to appropriate servers by mapping table names to datasets. + * + * A dataset is defined as a group of tables that are located in the same + * database. There may be similarly-named databases containing different + * tables on different servers. There may also be many replicas of a database + * on different servers. The term "dataset" removes any ambiguity. Consider a + * dataset as a group of tables that can be mirrored on many servers. + * + * Configuring HyperDB involves defining databases and datasets. Defining a + * database involves specifying the server connection details, the dataset it + * contains, and its capabilities and priorities for reading and writing. + * Defining a dataset involves specifying its exact table names or registering + * one or more callback functions that translate table names to datasets. + */ + + +/** Variable settings **/ + +/** + * save_queries (bool) + * This is useful for debugging. Queries are saved in $wpdb->queries. It is not + * a constant because you might want to use it momentarily. + * Default: false + */ +$wpdb->save_queries = false; + +/** + * persistent (bool) + * This determines whether to use mysql_connect or mysql_pconnect. The effects + * of this setting may vary and should be carefully tested. + * Default: false + */ +$wpdb->persistent = false; + +/** + * max_connections (int) + * This is the number of mysql connections to keep open. Increase if you expect + * to reuse a lot of connections to different servers. This is ignored if you + * enable persistent connections. + * Default: 10 + */ +$wpdb->max_connections = 30; + +/** + * tcp_responsiveness_check + * Enables checking TCP responsiveness by fsockopen prior to mysql_connect or + * mysql_pconnect. This was added because PHP's mysql functions do not provide + * a variable timeout setting. Disabling it may improve average performance by + * a very tiny margin but lose protection against connections failing slowly. + * Default: true + */ +$wpdb->tcp_responsiveness_check = true; + +/** Configuration Functions **/ + +/** + * $wpdb->add_database( $database ); + * + * $database is an associative array with these parameters: + * host (required) Hostname with optional :port. Default port is 3306. + * user (required) MySQL user name. + * password (required) MySQL user password. + * name (required) MySQL database name. + * read (optional) Whether server is readable. Default is 1 (readable). + * Also used to assign preference. See "Network topology". + * write (optional) Whether server is writable. Default is 1 (writable). + * Also used to assign preference in multi-master mode. + * dataset (optional) Name of dataset. Default is 'global'. + * timeout (optional) Seconds to wait for TCP responsiveness. Default is 0.2 + */ + +/** + * $wpdb->add_table( $dataset, $table ); + * + * $dataset and $table are strings. + */ + +/** + * $wpdb->add_callback( $callback ); + * + * $callback is a callable function or method. It will be called with two + * arguments and expected to compute a dataset or return null. + * $dataset = $callback($table, &$wpdb); + * + * Callbacks are executed in the order in which they are registered until one + * of them returns something other than null. Anything evaluating to false will + * cause the query to be aborted. + * + * For more complex setups, the callback may be used to overwrite properties of + * $wpdb or variables within hyperdb::connect_db(). If a callback returns an + * array, HyperDB will extract the array. It should be an associative array and + * it should include a $dataset value corresponding to a database added with + * $wpdb->add_database(). It may also include $server, which will be extracted + * to overwrite the parameters of each randomly selected database server prior + * to connection. This allows you to dynamically vary parameters such as the + * host, user, password, database name, and TCP check timeout. + */ + + +/** Masters and slaves + * + * A database definition can include 'read' and 'write' parameters. These + * operate as boolean switches but they are typically specified as integers. + * They allow or disallow use of the database for reading or writing. + * + * A master database might be configured to allow reading and writing: + * 'write' => 1, + * 'read' => 1, + * while a slave would be allowed only to read: + * 'write' => 0, + * 'read' => 1, + * + * It might be advantageous to disallow reading from the master, such as when + * there are many slaves available and the master is very busy with writes. + * 'write' => 1, + * 'read' => 0, + * HyperDB accommodates slave replication lag somewhat by keeping track of the + * tables that it has written since instantiation and sending subsequent read + * queries to the same server that received the write query. Thus a master set + * up this way will still receive read queries, but only subsequent to writes. + */ + + +/** + * Network topology / Datacenter awareness + * + * When your databases are located in separate physical locations there is + * typically an advantage to connecting to a nearby server instead of a more + * distant one. The read and write parameters can be used to place servers into + * logical groups of more or less preferred connections. Lower numbers indicate + * greater preference. + * + * This configuration instructs HyperDB to try reading from one of the local + * slaves at random. If that slave is unreachable or refuses the connection, + * the other slave will be tried, followed by the master, and finally the + * remote slaves in random order. + * Local slave 1: 'write' => 0, 'read' => 1, + * Local slave 2: 'write' => 0, 'read' => 1, + * Local master: 'write' => 1, 'read' => 2, + * Remote slave 1: 'write' => 0, 'read' => 3, + * Remote slave 2: 'write' => 0, 'read' => 3, + * + * In the other datacenter, the master would be remote. We would take that into + * account while deciding where to send reads. Writes would always be sent to + * the master, regardless of proximity. + * Local slave 1: 'write' => 0, 'read' => 1, + * Local slave 2: 'write' => 0, 'read' => 1, + * Remote slave 1: 'write' => 0, 'read' => 2, + * Remote slave 2: 'write' => 0, 'read' => 2, + * Remote master: 'write' => 1, 'read' => 3, + * + * There are many ways to achieve different configurations in different + * locations. You can deploy different config files. You can write code to + * discover the web server's location, such as by inspecting $_SERVER or + * php_uname(), and compute the read/write parameters accordingly. An example + * appears later in this file using the legacy function add_db_server(). + */ + + +/** Sample Configuration 1: Using the Default Server **/ +/** NOTE: THIS IS ACTIVE BY DEFAULT. COMMENT IT OUT. **/ + +/** + * This is the most basic way to add a server to HyperDB using only the + * required parameters: host, user, password, name. + * This adds the DB defined in wp-config.php as a read/write server for + * the 'global' dataset. (Every table is in 'global' by default.) + */ +/*$wpdb->add_database(array( + 'host' => DB_HOST, // If port is other than 3306, use host:port. + 'user' => DB_USER, + 'password' => DB_PASSWORD, + 'name' => DB_NAME, +));*/ + +/** + * This adds the same server again, only this time it is configured as a slave. + * The last three parameters are set to the defaults but are shown for clarity. + */ +/*$wpdb->add_database(array( + 'host' => DB_HOST, // If port is other than 3306, use host:port. + 'user' => DB_USER, + 'password' => DB_PASSWORD, + 'name' => DB_NAME, + 'write' => 0, + 'read' => 1, + 'dataset' => 'global', + 'timeout' => 0.2, +));*/ + +/** Sample Configuration 2: Partitioning **/ + +/** + * This example shows a setup where the multisite blog tables have been + * separated from the global dataset. + */ + +$wpdb->add_database(array( + 'host' => DB_HOST, // If port is other than 3306, use host:port. + 'user' => DB_USER, + 'password' => DB_PASSWORD, + 'name' => DB_NAME, + 'write' => 1, + 'read' => 1, + 'dataset' => 'global' +)); + +$wpdb->add_database(array( + 'host' => '172.16.1.3:3307', + 'user' => 'noblogs', + 'password' => 'n0bl0gst3st', + 'name' => 'noblogs_2', + 'dataset' => 'blog', + 'write' => 1, + 'read' => 1, + 'timeout' => 2, +)); +$wpdb->add_callback('my_db_callback'); +function my_db_callback($query, $wpdb) { + // Multisite blog tables are "{$base_prefix}{$blog_id}_*" + if ( preg_match("/^{$wpdb->base_prefix}\d+_/i", $wpdb->table) ) { + $table=split('_',$wpdb->table); + if (($table[1] % 2) == 0) { + return 'blog'; + } + } +} + + + +/** Sample helper functions from WordPress.com **/ + +/** + * This is back-compatible with an older config style. It is for convenience. + * lhost, part, and dc were removed from hyperdb because the read and write + * parameters provide enough power to achieve the desired effects via config. + * + * @param string $dataset Datset: the name of the dataset. Just use "global" if you don't need horizontal partitioning. + * @param int $part Partition: the vertical partition number (1, 2, 3, etc.). Use "0" if you don't need vertical partitioning. + * @param string $dc Datacenter: where the database server is located. Airport codes are convenient. Use whatever. + * @param int $read Read group: tries all servers in lowest number group before trying higher number group. Typical: 1 for slaves, 2 for master. This will cause reads to go to slaves unless all slaves are unreachable. Zero for no reads. + * @param bool $write Write flag: is this server writable? Works the same as $read. Typical: 1 for master, 0 for slaves. + * @param string $host Internet address: host:port of server on internet. + * @param string $lhost Local address: host:port of server for use when in same datacenter. Leave empty if no local address exists. + * @param string $name Database name. + * @param string $user Database user. + * @param string $password Database password. + */ +/* +function add_db_server($dataset, $part, $dc, $read, $write, $host, $lhost, $name, $user, $password, $timeout = 0.2 ) { + global $wpdb; + + // dc is not used in hyperdb. This produces the desired effect of + // trying to connect to local servers before remote servers. Also + // increases time allowed for TCP responsiveness check. + if ( !empty($dc) && defined(DATACENTER) && $dc != DATACENTER ) { + $read += 10000; + $write += 10000; + $timeout = 0.7; + } + + // You'll need a hyperdb::add_callback() callback function to use partitioning. + // $wpdb->add_callback( 'my_func' ); + if ( $part ) + $dataset = $dataset . '_' . $part; + + $database = compact('dataset', 'read', 'write', 'host', 'name', 'user', 'password', 'timeout'); + + $wpdb->add_database($database); + + // lhost is not used in hyperdb. This configures hyperdb with an + // additional server to represent the local hostname so it tries to + // connect over the private interface before the public one. + if ( !empty( $lhost ) ) { + if ( $read ) + $database['read'] = $read - 0.5; + if ( $write ) + $database['write'] = $write - 0.5; + $wpdb->add_database( $database ); + } +} +*/ + +// The ending PHP tag is omitted. This is actually safer than including it. diff --git a/db-config.php b/db-config.php index ca3793e19..cebe3a82f 100644 --- a/db-config.php +++ b/db-config.php @@ -1,300 +1,20 @@ <?php -/** - * HyperDB configuration file - * - * This file should be installed at ABSPATH/db-config.php - * - * $wpdb is an instance of the hyperdb class which extends the wpdb class. - * - * See readme.txt for documentation. - */ +define("NOBLOGS_BACKEND_CONFIG", "/etc/noblogs/backends"); -/** - * Introduction to HyperDB configuration - * - * HyperDB can manage connections to a large number of databases. Queries are - * distributed to appropriate servers by mapping table names to datasets. - * - * A dataset is defined as a group of tables that are located in the same - * database. There may be similarly-named databases containing different - * tables on different servers. There may also be many replicas of a database - * on different servers. The term "dataset" removes any ambiguity. Consider a - * dataset as a group of tables that can be mirrored on many servers. - * - * Configuring HyperDB involves defining databases and datasets. Defining a - * database involves specifying the server connection details, the dataset it - * contains, and its capabilities and priorities for reading and writing. - * Defining a dataset involves specifying its exact table names or registering - * one or more callback functions that translate table names to datasets. - */ - - -/** Variable settings **/ - -/** - * save_queries (bool) - * This is useful for debugging. Queries are saved in $wpdb->queries. It is not - * a constant because you might want to use it momentarily. - * Default: false - */ -$wpdb->save_queries = false; - -/** - * persistent (bool) - * This determines whether to use mysql_connect or mysql_pconnect. The effects - * of this setting may vary and should be carefully tested. - * Default: false - */ -$wpdb->persistent = false; - -/** - * max_connections (int) - * This is the number of mysql connections to keep open. Increase if you expect - * to reuse a lot of connections to different servers. This is ignored if you - * enable persistent connections. - * Default: 10 - */ -$wpdb->max_connections = 30; - -/** - * tcp_responsiveness_check - * Enables checking TCP responsiveness by fsockopen prior to mysql_connect or - * mysql_pconnect. This was added because PHP's mysql functions do not provide - * a variable timeout setting. Disabling it may improve average performance by - * a very tiny margin but lose protection against connections failing slowly. - * Default: true - */ -$wpdb->tcp_responsiveness_check = true; - -/** Configuration Functions **/ - -/** - * $wpdb->add_database( $database ); - * - * $database is an associative array with these parameters: - * host (required) Hostname with optional :port. Default port is 3306. - * user (required) MySQL user name. - * password (required) MySQL user password. - * name (required) MySQL database name. - * read (optional) Whether server is readable. Default is 1 (readable). - * Also used to assign preference. See "Network topology". - * write (optional) Whether server is writable. Default is 1 (writable). - * Also used to assign preference in multi-master mode. - * dataset (optional) Name of dataset. Default is 'global'. - * timeout (optional) Seconds to wait for TCP responsiveness. Default is 0.2 - */ - -/** - * $wpdb->add_table( $dataset, $table ); - * - * $dataset and $table are strings. - */ - -/** - * $wpdb->add_callback( $callback ); - * - * $callback is a callable function or method. It will be called with two - * arguments and expected to compute a dataset or return null. - * $dataset = $callback($table, &$wpdb); - * - * Callbacks are executed in the order in which they are registered until one - * of them returns something other than null. Anything evaluating to false will - * cause the query to be aborted. - * - * For more complex setups, the callback may be used to overwrite properties of - * $wpdb or variables within hyperdb::connect_db(). If a callback returns an - * array, HyperDB will extract the array. It should be an associative array and - * it should include a $dataset value corresponding to a database added with - * $wpdb->add_database(). It may also include $server, which will be extracted - * to overwrite the parameters of each randomly selected database server prior - * to connection. This allows you to dynamically vary parameters such as the - * host, user, password, database name, and TCP check timeout. - */ - - -/** Masters and slaves - * - * A database definition can include 'read' and 'write' parameters. These - * operate as boolean switches but they are typically specified as integers. - * They allow or disallow use of the database for reading or writing. - * - * A master database might be configured to allow reading and writing: - * 'write' => 1, - * 'read' => 1, - * while a slave would be allowed only to read: - * 'write' => 0, - * 'read' => 1, - * - * It might be advantageous to disallow reading from the master, such as when - * there are many slaves available and the master is very busy with writes. - * 'write' => 1, - * 'read' => 0, - * HyperDB accommodates slave replication lag somewhat by keeping track of the - * tables that it has written since instantiation and sending subsequent read - * queries to the same server that received the write query. Thus a master set - * up this way will still receive read queries, but only subsequent to writes. - */ - - -/** - * Network topology / Datacenter awareness - * - * When your databases are located in separate physical locations there is - * typically an advantage to connecting to a nearby server instead of a more - * distant one. The read and write parameters can be used to place servers into - * logical groups of more or less preferred connections. Lower numbers indicate - * greater preference. - * - * This configuration instructs HyperDB to try reading from one of the local - * slaves at random. If that slave is unreachable or refuses the connection, - * the other slave will be tried, followed by the master, and finally the - * remote slaves in random order. - * Local slave 1: 'write' => 0, 'read' => 1, - * Local slave 2: 'write' => 0, 'read' => 1, - * Local master: 'write' => 1, 'read' => 2, - * Remote slave 1: 'write' => 0, 'read' => 3, - * Remote slave 2: 'write' => 0, 'read' => 3, - * - * In the other datacenter, the master would be remote. We would take that into - * account while deciding where to send reads. Writes would always be sent to - * the master, regardless of proximity. - * Local slave 1: 'write' => 0, 'read' => 1, - * Local slave 2: 'write' => 0, 'read' => 1, - * Remote slave 1: 'write' => 0, 'read' => 2, - * Remote slave 2: 'write' => 0, 'read' => 2, - * Remote master: 'write' => 1, 'read' => 3, - * - * There are many ways to achieve different configurations in different - * locations. You can deploy different config files. You can write code to - * discover the web server's location, such as by inspecting $_SERVER or - * php_uname(), and compute the read/write parameters accordingly. An example - * appears later in this file using the legacy function add_db_server(). - */ - - -/** Sample Configuration 1: Using the Default Server **/ -/** NOTE: THIS IS ACTIVE BY DEFAULT. COMMENT IT OUT. **/ - -/** - * This is the most basic way to add a server to HyperDB using only the - * required parameters: host, user, password, name. - * This adds the DB defined in wp-config.php as a read/write server for - * the 'global' dataset. (Every table is in 'global' by default.) - */ -/*$wpdb->add_database(array( - 'host' => DB_HOST, // If port is other than 3306, use host:port. - 'user' => DB_USER, - 'password' => DB_PASSWORD, - 'name' => DB_NAME, -));*/ - -/** - * This adds the same server again, only this time it is configured as a slave. - * The last three parameters are set to the defaults but are shown for clarity. - */ -/*$wpdb->add_database(array( - 'host' => DB_HOST, // If port is other than 3306, use host:port. - 'user' => DB_USER, - 'password' => DB_PASSWORD, - 'name' => DB_NAME, - 'write' => 0, - 'read' => 1, - 'dataset' => 'global', - 'timeout' => 0.2, -));*/ - -/** Sample Configuration 2: Partitioning **/ - -/** - * This example shows a setup where the multisite blog tables have been - * separated from the global dataset. - */ - -$wpdb->add_database(array( - 'host' => DB_HOST, // If port is other than 3306, use host:port. - 'user' => DB_USER, - 'password' => DB_PASSWORD, - 'name' => DB_NAME, - 'write' => 1, - 'read' => 1, - 'dataset' => 'global' -)); +require_once('r2db/db-hash.php'); +require_once('r2db/db-backends.php'); +// Add the global database (configured in wp-config.php), stores the global +// blogs and users tables. $wpdb->add_database(array( - 'host' => '172.16.1.3:3307', - 'user' => 'noblogs', - 'password' => 'n0bl0gst3st', - 'name' => 'noblogs_2', - 'dataset' => 'blog', - 'write' => 1, - 'read' => 1, - 'timeout' => 2, -)); -$wpdb->add_callback('my_db_callback'); -function my_db_callback($query, $wpdb) { - // Multisite blog tables are "{$base_prefix}{$blog_id}_*" - if ( preg_match("/^{$wpdb->base_prefix}\d+_/i", $wpdb->table) ) { - $table=split('_',$wpdb->table); - if (($table[1] % 2) == 0) { - return 'blog'; - } - } -} - - - -/** Sample helper functions from WordPress.com **/ - -/** - * This is back-compatible with an older config style. It is for convenience. - * lhost, part, and dc were removed from hyperdb because the read and write - * parameters provide enough power to achieve the desired effects via config. - * - * @param string $dataset Datset: the name of the dataset. Just use "global" if you don't need horizontal partitioning. - * @param int $part Partition: the vertical partition number (1, 2, 3, etc.). Use "0" if you don't need vertical partitioning. - * @param string $dc Datacenter: where the database server is located. Airport codes are convenient. Use whatever. - * @param int $read Read group: tries all servers in lowest number group before trying higher number group. Typical: 1 for slaves, 2 for master. This will cause reads to go to slaves unless all slaves are unreachable. Zero for no reads. - * @param bool $write Write flag: is this server writable? Works the same as $read. Typical: 1 for master, 0 for slaves. - * @param string $host Internet address: host:port of server on internet. - * @param string $lhost Local address: host:port of server for use when in same datacenter. Leave empty if no local address exists. - * @param string $name Database name. - * @param string $user Database user. - * @param string $password Database password. - */ -/* -function add_db_server($dataset, $part, $dc, $read, $write, $host, $lhost, $name, $user, $password, $timeout = 0.2 ) { - global $wpdb; - - // dc is not used in hyperdb. This produces the desired effect of - // trying to connect to local servers before remote servers. Also - // increases time allowed for TCP responsiveness check. - if ( !empty($dc) && defined(DATACENTER) && $dc != DATACENTER ) { - $read += 10000; - $write += 10000; - $timeout = 0.7; - } - - // You'll need a hyperdb::add_callback() callback function to use partitioning. - // $wpdb->add_callback( 'my_func' ); - if ( $part ) - $dataset = $dataset . '_' . $part; - - $database = compact('dataset', 'read', 'write', 'host', 'name', 'user', 'password', 'timeout'); - - $wpdb->add_database($database); + "host" => DB_HOST, + "user" => DB_USER, + "password" => DB_PASSWORD, + "name" => DB_NAME, + "dataset" => "global", + "write" => 1, "read" => 1, "timeout" => 2 + )); - // lhost is not used in hyperdb. This configures hyperdb with an - // additional server to represent the local hostname so it tries to - // connect over the private interface before the public one. - if ( !empty( $lhost ) ) { - if ( $read ) - $database['read'] = $read - 0.5; - if ( $write ) - $database['write'] = $write - 0.5; - $wpdb->add_database( $database ); - } -} -*/ +$wpdb_reverse_backend_map = noblogs_load_backends(NOBLOGS_BACKEND_CONFIG, $wpdb_hash); -// The ending PHP tag is omitted. This is actually safer than including it. diff --git a/r2db/README b/r2db/README new file mode 100644 index 000000000..1a08b493d --- /dev/null +++ b/r2db/README @@ -0,0 +1,15 @@ + +Uso di HyperDB con il piano R di A/I +------------------------------------ + +I database di noblogs sono distribuiti su piu' di un backend, utilizzando +un sistema di consistent hashing che associa ogni blog_id ad un backend +specifico. + +L'elenco dei backend e' specificato nel file /etc/noblogs/backends. + +Lo schema e' molto semplice e si basa sull'ID pubblico di ciascun server +(es, latitanza:1, confino:3, etc). Ogni server ha un database 'noblogs_ID' +(in /opt/noblogs/mysql), cui puo' accedere l'utente 'noblogsdb'. + + diff --git a/r2db/db-backends.php b/r2db/db-backends.php new file mode 100644 index 000000000..af791645d --- /dev/null +++ b/r2db/db-backends.php @@ -0,0 +1,35 @@ +<?php + +function noblogs_load_backends($db_config_file, &$hashptr) { + global $wpdb; + + $backend_map = array(); + + $fp = @fopen($db_config_file, "r"); + if (!$fp) { + die("Database backends not configured!"); + } + while (($line = fgets($fp, 1024)) !== false) { + if ($line[0] == '#') { + continue; + } + $line_parts = explode(" ", rtrim($line)); + $server_id = $line_parts[0]; + $dataset = "backend_" . $server_id; + $backend_url = $line_parts[2]; + $backend_url_data = parse_url($backend_url); + $backend = array( + "host" => $backend_url_data["host"] . ":" . $backend_url_data["port"], + "user" => $backend_url_data["user"], + "password" => $backend_url_data["pass"], + "name" => substr($backend_url_data["path"], 1), + "dataset" => $dataset, + "read" => 1, "write" => 1, "timeout" => 2 + ); + $wpdb->add_database($backend); + $hashptr->addTarget($dataset); + $backend_map[$dataset] = $backend; + } + fclose($fp); + return $backend_map; +} diff --git a/db-hash.php b/r2db/db-hash.php similarity index 100% rename from db-hash.php rename to r2db/db-hash.php diff --git a/flexihash.php b/r2db/flexihash.php similarity index 100% rename from flexihash.php rename to r2db/flexihash.php diff --git a/r2db/tools/db-migrate-to-new-schema.php b/r2db/tools/db-migrate-to-new-schema.php new file mode 100755 index 000000000..e393de019 --- /dev/null +++ b/r2db/tools/db-migrate-to-new-schema.php @@ -0,0 +1,94 @@ +#!/opt/noblogs/cron/php-noblogs +<?php + +// Load wordpress api. +define('WP_CACHE',false); +/** Setup WordPress environment */ +require_once('wp-load.php'); +require_once('db-config-new.php'); + + +function old_hash($dbid) { + if (($dbid % 2) == 0) { + return array('host' => '172.16.1.3', + 'port' => '3307', + 'user' => 'noblogs', + 'password' => 'n0bl0gst3st', + 'db' => 'noblogs_2'); + } else { + return array('host' => '172.16.1.8', + 'port' => '3307', + 'user' => 'noblogsusr', + 'password' => 'n0bl0gsdb4xpw!', + 'db' => 'noblogs'); + } +} + +function new_hash($dbid) { + global $wpdb_hash; + global $wpdb_reverse_backend_map; + $lookup = $wpdb_hash->lookup($dbid); + $backend = $wpdb_reverse_backend_map[$lookup]; + $result = array(); + if (preg_match('/^(.*):([0-9]*)$/', $backend['host'], $matches)) { + $result['host'] = $matches[1]; + $result['port'] = $matches[2]; + } + $result['user'] = $backend['user']; + $result['password'] = $backend['password']; + $result['db'] = $backend['name']; + return $result; +} + +function mysqlopts(&$attrs) { + return ("-h" . $attrs['host'] . " -P" . $attrs['port'] . " -u" . $attrs['user'] + . " '-p" . $attrs['password'] . "'"); +} + +function mysqlurl(&$attrs) { + return ("mysql://" . $attrs['user'] . "@" . $attrs['host'] + . ":" . $attrs['port'] . "/" . $attrs['db']); +} + +function get_all_blogs() +{ + global $wpdb; + + $sql = "SELECT blog_id, domain, path FROM $wpdb->blogs WHERE public = 1 AND deleted = 0 AND archived = '0' ORDER BY domain, path"; + $result = $wpdb->get_results($sql); + return ($result); +} + +$new_counts = array(); +$moved_count = 0; +$blogs = get_all_blogs(); +foreach ($blogs as $blog) { + $blog_id = $blog->blog_id; + + $old_params = old_hash($blog_id); + $old_dburi = mysqlurl($old_params); + $new_params = new_hash($blog_id); + $new_dburi = mysqlurl($new_params); + + if ($new_counts[$new_params['host']]) { + $new_counts[$new_params['host']] += 1; + } else { + $new_counts[$new_params['host']] = 1; + } + + if ($old_dburi != $new_dburi) { + echo "echo moving blog $blog_id from " . $old_params['host'] . " to " . $new_params['host'] . "\n"; + echo "tables=\$(mysql " . mysqlopts($old_params) . " " . $old_params['db'] . " -NBe \"show tables like 'wp\\_" . $blog_id . "\\_%'\")\n"; + echo "mysqldump --opt " . mysqlopts($old_params) . " " . $old_params['db'] . " \${tables} \\\n"; + echo " | mysql " . mysqlopts($new_params) . " " . $new_params['db'] . "\n"; + $moved_count += 1; + } else { + echo "echo blog $blog_id stays on " . $old_params['host'] . "\n"; + } + +} + +echo "\n\n\nBlog distribution:\n"; +print_r($new_counts); +print "\n $moved_count blogs moved\n"; + -- GitLab