2 http://cvs.drupal.org/viewcvs/drupal/contributions/sandbox/crackerjm/replication/
4 --- /dev/null 2005-02-16 21:06:48.000000000 +0200
5 +++ ./README.replication 2005-08-15 16:08:52.000000000 +0300
8 +This README.txt and patch are for Mysql Replication. This assumes that you have
9 +a master replication server and slave server(s) up and running already. If
10 +you don't, then there is no purpose for reading this. If you need help for
11 +replication, please read this link.
12 + http://dev.mysql.com/doc/mysql/en/Replication.html
14 +NOTE: This is meant for drupal 4.6.0
16 +Now, in includes/conf.php you have a line that looks simalar to this
17 + $db_url = "mysql://username:password@localhost/database";
18 +Comment at the line so that it looks like this
19 + //$db_url = "mysql://username:password@localhost/database";
21 +Add the following lines below it to look like this:
23 + $db_url['default'] = "mysql://username:password@localhost/database";
24 + $db_url['slave1'] = "mysql://username:password@host/database";
25 + //$db_url['slave2'] = "mysql://username:password@host/database";
27 +The 'default' is your MASTER server, the slaves are just that. make
28 +sure that you have added the appropriate users to the servers so that
29 +if you are using round robin DNS or something to that effect, that
30 +way you don't end up with permission denied.
32 +patch your code with replication.patch and there ya go
35 +NEW: This revision of code supports the dead slave servers!
36 + caveat though, if ALL of your slaves are dead, then you will
37 + end up in a infinitely recursive loop searching for slave servers.
38 + Hopefully in the next revision of this, I will try to come up with
39 + a way to stop this recursion without the use of flags.
41 diff -urN drupal-4.6.0/includes/database.inc drupal-test/includes/database.inc
42 --- drupal-4.6.0/includes/database.inc 2005-04-08 09:24:10.000000000 -0500
43 +++ drupal-test/includes/database.inc 2005-05-29 09:30:18.710563836 -0500
45 die('Unsupported database type');
48 - $db_conns[$name] = db_connect($connect_url);
50 + if($name == 'default') {
52 + $db_conns[$name] = db_connect($connect_url, true);
55 + $db_conns[$name] = db_connect($connect_url);
59 // Set the active connection.
60 - $active_db = $db_conns[$name];
61 + if($name != 'default' && $db_conns[$name] === false){
62 + print "Bad slave, killing $name\n";
63 + db_find_slave(true); // kill bad slave
64 + db_set_active(db_find_slave());
67 + $active_db = $db_conns[$name];
71 +function _is_commit($query) {
72 + $commits = array('insert', 'alter', 'update', 'delete', 'flush', 'lock');
73 + foreach($commits as $type) {
74 + if(preg_match("/^$type/i", $query)) {
81 +function db_find_slave($killslave = false) {
85 + if(!_replication_ready())
88 + if(!is_array($slave)){
90 + // initialize a local copy
91 + foreach($db_url as $key=>$value) {
92 + if(stristr($key, 'slave')) {
97 + * Since this is the first iteration of the loop, we reset the array to
98 + * ensure we return the first element.
100 + return reset($slave);
103 + if(empty($slave)) {
107 + // Failed to connect, remove from the list
109 + array_shift($slave);
112 + $url = next($slave);
114 + if($url === false){
115 + // walked past of the end of the array, start over at first element
116 + $url = reset($slave);
122 +function _replication_ready() {
126 + if(isset($ready)) {
130 + if(is_array($db_url)) {
131 + foreach($db_url as $key=>$value) {
132 + if(stristr($key, 'slave')) {
133 + // Found at least ONE element with the word slave in it
134 + // break the search to save on cycles
146 diff -urN drupal-4.6.0/includes/database.mysql.inc drupal-test/includes/database.mysql.inc
147 --- drupal-4.6.0/includes/database.mysql.inc 2005-04-14 13:50:23.000000000 -0500
148 +++ drupal-test/includes/database.mysql.inc 2005-05-29 09:28:22.490546558 -0500
150 * performance, however, when the overhead to connect to your database is high
151 * (e.g. your database and web server live on different machines).
153 -function db_connect($url) {
154 +function db_connect($url, $critical = false) {
155 $url = parse_url($url);
157 // Allow for non-standard MySQL port.
159 $url['host'] = $url['host'] .':'. $url['port'];
162 - $connection = mysql_connect($url['host'], $url['user'], $url['pass'], TRUE) or die(mysql_error());
163 - mysql_select_db(substr($url['path'], 1)) or die('unable to select database');
164 + // For replication setups, we will assume that dieing is bad
165 + $connection = mysql_pconnect($url['host'], $url['user'], $url['pass'], TRUE);
166 + if(!is_resource($connection) && $critical) {
167 + die(mysql_error());
169 + // We die on bad slaves. These should be taken care of
170 + // maybe hook this somehow or something
171 + mysql_select_db(substr($url['path'], 1)) or die(mysql_error());
173 - return $connection;
174 + return ($connection)?$connection:false;
179 function _db_query($query, $debug = 0) {
184 if (variable_get('dev_query', 0)) {
185 list($usec, $sec) = explode(' ', microtime());
186 $timer = (float)$usec + (float)$sec;
190 + * If the db_url isn't an array, then we can assume that this server is not
191 + * ready for a replication setup. This outer if is purely for a speed as
192 + * calling PHP's builtin functions are way faster than user functions.
193 + * So, if its an array and has more than one element, we shall atleast check
194 + * to see if it's possibly ready for a replication enviorment. However,
195 + * if no [slave#] elements are found, then we assume normal operations.
197 + if(is_array($db_url) && sizeof($db_url) > 1 && _replication_ready() )
199 + if (_is_commit($query) === true){
200 + db_set_active('default');
204 + // no checks as _replication_ready() verifies
205 + // that there is atleast one slave
206 + db_set_active(db_find_slave());
211 $result = mysql_query($query, $active_db);
214 if (variable_get('dev_query', 0)) {
215 list($usec, $sec) = explode(' ', microtime());
216 $stop = (float)$usec + (float)$sec;
223 * Fetch one result row from the previous query as an object.
226 * @} End of "ingroup database".
230 \ No newline at end of file
232 --- ./sites/default/settings.php~ 2005-08-15 16:41:07.000000000 +0300
233 +++ ./sites/default/settings.php 2005-08-15 16:42:47.000000000 +0300
235 * Database URL format:
236 * $db_url = 'mysql://username:password@localhost/database';
237 * $db_url = 'pgsql://username:password@localhost/database';
239 + * Database URL format with MySQL replication:
240 + * $db_url = array();
241 + * $db_url['default'] = "mysql://username:password@localhost/database";
242 + * $db_url['slave1'] = "mysql://username:password@host/database";
244 -$db_url = 'mysql://username:password@localhost/database';
246 +$db_url['default'] = 'mysql://mysql:@localhost/drupal';
247 +#$db_url['slave1'] = "mysql://mysql:@mysql-slave/drupal";