tags:

views:

59

answers:

5

Hi, I am trying to use PHP and MySQL's Create Table Select between two different MySQL servers. I am not sure this can be done like this with SQL. I get no errors but I get nothing done either:

<?php
$dbname = 'cms';
$dbmaster = 'cmsms';

$db1 = mysql_connect('localhost', 'root', 'secret');
if (!$db1) {
    echo 'Could not connect to mysql';
    exit;
}

$db2 = mysql_connect('server2', 'root', 'secret');
if (!$db2) {
    echo 'Could not connect to mysql';
    exit;
}

mysql_select_db("$dbname", $db1) or die ("Unable to select database");
mysql_select_db("$dbmaster", $db2) or die ("Unable to select database");

$sql = "SHOW TABLES FROM $dbname";
$result = mysql_query($sql, $db1);

if (!$result) {
    echo "DB Error, could not list tables\n";
    echo 'MySQL Error: ' . mysql_error();
    exit;
}

while ($row = mysql_fetch_row($result)) {
    $sql = "DROP TABLE `$row[0]`";
    mysql_query($sql, $db1);
    echo "Table rows: {$row[0]} Deleted <br/>";
    $sql = "CREATE TABLE $row[0] SELECT * FROM $db2.$dbmaster.$row[0] ";
    mysql_query($sql, $db1);
    echo "Table: {$row[0]} created <br/>";

}
echo "<br/>done...";

mysql_free_result($result);
?>

That line:

$sql = "CREATE TABLE $row[0] SELECT * FROM $db2.$dbmaster.$row[0] ";

just doesn't work. the $db2 doesn't make it go to the other server and select.

From doing some reading on SO I found someone similar and someone said it could not be done and to look at federated tables, which will not work for me.

If this cannot be done above does anyone know a way to do what I am doing? I am dropping the tables on the copy and re-creating them based on the table in the master. Then I am selecting the data in the master to put in the re-created tables. Thank you

Update: Just so I can be clear. The code works if everything were on the same server and I only had one database connection. It is because of the create table select that I have problems, I believe. This SQL needs to use two servers at the same time. The create table is for one database that just dropped it's tables but the select is selecting from the database of the second connection - two connections in the same SQL statement.

+6  A: 

Yes, on your PHP script you can perform all queries you want on all different servers you have access and permission to.

You don't specify your database on the $sql though. You specify it when you run the mysql_query function.

So, your code:

$sql = "SHOW TABLES FROM $dbname";
$result = mysql_query($sql, $db1);

Is wrong. It should only be:

$sql = "SHOW TABLES";
$result = mysql_query($sql, $db1);

By using $db1 on the second parameter of mysql_query you are already specifying that you want to show tables from that database only.

Following the same reasoning on the other sentences, you should be able to get results you want.

You won't be able to do this:

$sql = "CREATE TABLE $row[0] SELECT * FROM $db2.$dbmaster.$row[0] ";

If you want to insert rows from $db2 into newly created tables into $db1, you need to:

  1. Run a query on $db2 to get results
  2. Create table on $db1
  3. Iterate $db2 results
  4. Insert records on new table on $db1

There is no magic way of doing this in only one sentence.

Pablo Santa Cruz
The problem is in the Create Select Insert. That statement is encompassing two server. First it creates the new table on server one, but the select is from server two. So I'm not sure how this will help me. I am hoping I just don't understand something easy. Thanks.
johnny
No. You won't be able to INSERT DIRECTLY with one sentence from one server into the other. You need to: run the query on SERVER1, create the TABLE on SERVER2, populate new table with results from query run on SERVER1. There's no straight way of doing that, you will have to perform inserts on separate sentences.
Pablo Santa Cruz
@pablo won't that mean spelling out all the columns like: insert into tbl1 (a, b, c, ...) values (a,b,c,...) for each table?
johnny
@johnny: yes, but you can always generate sentences from METADATA if you need.
Pablo Santa Cruz
@pablo also won't I have to do a very complete create table to get my structure right since I can't use the create table select?
johnny
@johnny again, you can use METADATA to create your new tables. But you WON'T be able to do the way you are trying. It is just not possible.
Pablo Santa Cruz
@pablo I think I will have to use dump of mysql on the server and get php to read that file on the copy. Thanks.
johnny
A: 

remove the $db2 database connection from your query

If you want to run SQL on $db1 use this

mysql_query($sql, $db1);

If you want to run SQL on $db2 use this

mysql_query($sql, $db2);
Phill Pafford
The problem is that create select uses two servers.
johnny
A: 

I don't think this is the best database design Johnny, depends of course on what you're trying to achieve. If you simply want to store data on both servers for redundancy, you should go with MySQL Replication. If you're separating data for high availability purposes, then consider data sharding, partitioning and definitely take a look at MySQL Proxy.

These will let you do all the work outside your application, so you wouldn't have to alter your application in case your sharding/partitioning/backup/redundancy scheme changes. Such tools make this completely invisible to your application.

Sorry if this is off-topic.

kovshenin
+3  A: 

You're on the right track but missing an important point. Your PHP code has opened a connection to db1 and db2 but that doesn't mean that the db1 server knows about the db2 server. Therefore you can't pass db1 a query with db2 in it and expect it to get rows from it. Your PHP script has to act as an intermediary.

You need to issue a select statement to select rows from db1's table, then loop over the results issuing insert statements for db2. Of course you do this after you issue a create table statement to create the blank table. I'm also assuming you're trying the 'create table select from' trick because you don't know how to issue the create table to copy the layout of the table in db1. Have you seen this?

http://dev.mysql.com/doc/refman/5.0/en/show-create-table.html

bot403
@bot403 I am doing create table select for that reason but I don't know another way to do it. I'm not sure what you were telling me in the link you provided. It just showed me the create table statement. thank you for understanding my code.
johnny
Sorry. What I'm saying is if you want to recreate the table in db2 exactly as it is in db1 you can issue that statement on db1 then take the create statement it gave you and issue that statement on db2 to get an exact copy of the table definition. Once you have the table created you can fill it with data as I suggested above.
bot403
A: 

There are a few choices you have in regards to setting this up.

1) Implement mysql asynchronous replication. This would do the same thing you are trying to do in PHP but would be much more efficient. Mysql Documentation: Replication

2) Fix your script to stream data from master server to backup server. This would be done by creating the table and then loading the result row by row into the backup server's table.

CtRanger