auto sync two mysql tables with exception - php

i have 2 sql tables of a script that i need to be sync to another, this can be done with php cron (this was my plan) exept from one row
Table 1 Table 2
row 1 <----> Row 1
Row 2 <----> row 2
row 3 no sync row 3
both databases on same server
and the same user has full rights for both
i am looking for a php code to do this via a cpanel cron
on an after thought would it be best to merge the two so both updates with new data?
the issue is that in the example above i am needing row 3 to not change on both databases
I am very noob so please be nice lol Thx in advance
Update *
i should learn how to explain a bit better.
both the databases are control panels for sites, one of the tables rows has the system url in it, so if i share the database "site 2" links refers back to "site 1" this is a complex problem for me as i am very new to this.
what i need is to keep both databases upto date except that single row which in turn be different for both databases.
i have not tried anything just yet as i wouldn't know where to start :( lol

You dont have to use cron. MySQL in current version supports TRIGGERS and EVENTS.
You can use TRIGGER to copy data to another table. That copy (or any other operation) may be triggered by some event (like insert, update or delete in table). TRIGGER may run any query or any PL/SQL code.
Other option is an EVENT. This is something like internal task sheduler built in MySQL. It can also run queries, or any PL/SQL code, but it is triggered by system time (like Linux Cron). It has many advantages compared to cron.
PL/SQL is procedural SQL, with loops, variables and more.
If you think you are "noob" - i have cure for you. Read books about MySQL or if you are lazy - watch some tutorials ( http://thenewboston.org , http://phpacademy.org ).
Nobody here will write code for you. We can only fix a bug, give advice etc. :)
EDIT.
Example of EVENT:
-- this is comment in SQL language (line starts with --)
CREATE EVENT event_daily_copy_something
ON SCHEDULE
EVERY 1 DAY
COMMENT 'This text will appear in MySQL Workbench as description of event'
DO
BEGIN
INSERT INTO your_db_name.target_table_name(id, field)
SELECT id, something
FROM your_db_name.source_table_name
WHERE id = 3;
END
Synchronization of tables is quite complicated. I think you need few operations in event.
Check for new rows and copy
Check for deleted rows and delete them in "copy" table
Check for changed rows (here trigger on source table would be very useful, because trigger "knows" what row is edited and you can access new field values in table 1 and use them to update table 2).
One of MySQL tutorials - thenewboston#youtube.

Related

Mysql table is adding rows itself

Short Story: I wrote a code in a loop that insert rows into mysql table, and kept it running for 3 hours accidentally. I tried to empty the mysql table, but then again it automatically starts to insert rows. I even tried to drop and re-create it, but it is automatically inserting rows (id in increasing order)
Full story:
2 days ago, I wrote a code that use an API and insert the data into mysql table (in a loop). And to mesure, how many records I have added, I made an table named "lastrequestdone" and started to insert the id number after every record inserted successfully.
But the code inserted all the ID's in 1 hour, and after that, the API started to give error:404 response, and the loop started to run very fast.
So assume that, I ran a loop for 3 hours, that insert an id in increasing order. But once i realized it, I stopped the loop. Tried to empty the table, but whenever I empty the table, more rows automatically starts to get inserted.
Then i dropped the table, and created it again today, but the same thing is happening. Rows are getting inserted automatically.
Look for the processes in your MySQL Server using any UI tools like MySQL Workbench or likes of it and try to find the process of the query that you left running and stop that particular process. You should probably resolve it this way.
Hope it might help you - https://dba.stackexchange.com/questions/63302/how-to-stop-the-execution-of-a-long-running-insert-query
Do you mean by "kill / stop the MySQL instance" the linux command kill -9 ...?
Yes, this might lead to corrupt data.
Which instead should not leave corrupt data is the build-in kill command of MySQL. See the lower part of the page, which states that it might take the thread some time to actually notice the presence of the kill flag. The part which states it does not roll back updates when transactions are not used (which implies that it rolls back updates if transactions are used), etc. I therefore assume this does not corrupt any data (besides killing repair and optimize as noted there).
You can find out the thread id you need for this command with the command show processlist.

How to copy my table to a dump table and deletes the values in the main table

I am working on php codeigniter framework with mysql workbech as back end tool...I have a doubt regarding executing one of the sql query that should be scheduled for one month....like I will explain it in clear...
I have a table named packet data in that table I will get 700K of records per day so totally for 1 month I may get 200K records roughly..and my application runs mainly on this table so because of this, my application runs slow....
So I want to move every month of data to a dump table and should be deleted from the main table so that my application may run fast....
This copying of 1 month data should be done every month and should be deleted form the main table.....
Please can anybody give me the solution how to perform the same delete and copy queries that should be performed in the same query....and whether it is possible or not can you tell me....
Can you try this code :-
INSERT INTO table1 (col`)
SELECT col
FROM table2
WHERE month(col)=month(curdate() - INTERVAL 1 month)
http://www.sitepoint.com/how-to-create-mysql-events/
You can create a mysql event which will do this. The link above explain it brifely but MySQL Events are tasks that run according to a schedule. Therefore, we sometimes refer to them as scheduled events. When you create an event, you are creating a named database object containing one or more SQL statements to be executed at one or more regular intervals, beginning and ending at a specific date and time.
there are a few other options like cron events however i would recommend using mysql events because they are made for these types of queries.
There is an example from the website link.
DELIMITER $$
CREATE
EVENT `archive_blogs`
ON SCHEDULE EVERY 1 WEEK STARTS '2011-07-24 03:00:00'
DO BEGIN
-- copy deleted posts
INSERT INTO blog_archive (id, title, content)
SELECT id, title, content
FROM blog
WHERE deleted = 1;
-- copy associated audit records
INSERT INTO audit_archive (id, blog_id, changetype, changetime)
SELECT audit.id, audit.blog_id, audit.changetype, audit.changetime
FROM audit
JOIN blog ON audit.blog_id = blog.id
WHERE blog.deleted = 1;
-- remove deleted blogs and audit entries
DELETE FROM blog WHERE deleted = 1;
END */$$
DELIMITER ;
BTW: I do not know too much about your database design, business model or even what type of queries you are running however if you are copying the data over for backup reasons then I would rethink your database design and also think about weather or not you need to store the data in another table or exporting it as a csv file and holding csv files as backup is a more appropriate. Storing Csv files could be a better solution depending on weather or not you need to access that data again through out the months. Think about it however creating a mysql event would do what you wanted to do.

How to check in real-time if new row was added to MySQL table

We have an automatic car plate reader which records plates of the cars enter to firm. My colleague asked me if we can instantly get the plate number of the car coming. The software uses MySQL and I have only database access. Cannot reach/edit PHP codes.
My offer is to check using a query periodically. For example for 10 seconds. But in this way it is possible to miss the cars coming in 5 seconds. Then decreasing interval increases request/response count which means extra load for the server. I do not want the script to run always. It should run only a new db row added. It shows the plate and exits.
How can I get last recorded row from the db right after inserting? I mean there should be trigger which runs my PHP script after insertion. But I do not know.
What I want is MySQL could run my PHP script after a new record.
If your table is MyISAM, I would stick to your initial idea. Getting the row count from a MyISAM table is instant. It only takes the reading of one single value as MyISAM maintains the row count at all times.
With InnoDB, this approach can still be acceptable. Assuming car_table.id is primary key, SELECT COUNT(id) FROM car_table only requires an index scan, which is very fast. You can improve on this idea by adding another indexed boolean column to your table:
ALTER car_table ADD COLUMN checked BOOLEAN NOT NULL DEFAULT 0, ADD INDEX (checked);
The default value ensures new cars will be inserted with this flag set to 0 without modifying the inserting statement. Then:
BEGIN TRANSACTION; -- make sure nobody interferes
SELECT COUNT(checked) FROM car_table WHERE checked = FALSE FOR UPDATE; -- this gets you the number of new, unchecked cars
UPDATE car_table SET checked = TRUE WHERE checked = FALSE; -- mark these cars as checked
COMMIT;
This way, you only scan a very small number of index entries at each polling.
A more advanced approach consists in adding newly created cars ID's into a side table, through a trigger. This side table is scanned every now and then, without locking the main table, and without altering its structure. Simply TRUNCATE this side table after each polling.
Finally, there is the option of triggering a UDF, as suggested by Panagiotis, but this seems to be an overkill in most situations.
Although this is not the greatest of designs and I have not implemented it, there is way to call an external script through sys_exec() UDF using a trigger as mentioned here:
B.5.11: Can triggers call an external application through a UDF?
Yes. For example, a trigger could invoke the sys_exec() UDF.
http://dev.mysql.com/doc/refman/5.1/en/faqs-triggers.html#qandaitem-B-5-1-11
Also have a look on this thread which is similar to your needs.
Invoking a PHP script from a MySQL trigger

MySQL mixed table query

I am not an SQL magician so I'm venturing to ask for help. I have 4 tables to insert into a 5th one while checking a 6th table to ensure no duplicates. For example, no names in the 6th table can be inserted in the 5th one. I probably can try to figure out the best SQL query for the job but my head can't get around the right method? The final table size is small for now (5000 contact names), but will grow every month so I got to start right. I plan to use a PHP script with mysql connection to the database. This script will only run on my server (CenTOS 5).
Without seeing the schema, in general if you're going to prevent rows from entering tables based on other tables - in mySQL you'll need to utilize foreign keys. Overall, all of this will need to be done in a database transaction so that whatever logic you create in PHP to insert rows in various tables either succeed after total confirmation of success or fail and roll back to the prior state.

Archive MySQL data using PHP every week

I have a MySQL DB that receives a lot of data from a source once every week on a certain day of the week at a given time (about 1.2million rows) and stores it in, lets call it, the "live" table.
I want to copy all the data from "live" table into an archive and truncate the live table to make space for the next "current data" that will come in the following week.
Can anyone suggest an efficient way of doing this. I am really trying to avoid -- insert into archive_table select * from live --. I would like the ability to run this archiver using PHP so I cant use Maatkit. Any suggestions?
EDIT: Also, the archived data needs to be readily accessible. Since every insert is timestamped, if I want to look for the data from last month, I can just search for it in the archives
The sneaky way:
Don't copy records over. That takes too long.
Instead, just rename the live table out of the way, and recreate:
RENAME TABLE live_table TO archive_table;
CREATE TABLE live_table (...);
It should be quite fast and painless.
EDIT: The method I described works best if you want an archive table per-rotation period. If you want to maintain a single archive table, might need to get trickier. However, if you're just wanting to do ad-hoc queries on historical data, you can probably just use UNION.
If you only wanted to save a few periods worth of data, you could do the rename thing a few times, in a manner similar to log rotation. You could then define a view that UNIONs the archive tables into one big honkin' table.
EDIT2: If you want to maintain auto-increment stuff, you might hope to try:
RENAME TABLE live TO archive1;
CREATE TABLE live (...);
ALTER TABLE LIVE AUTO_INCREMENT = (SELECT MAX(id) FROM archive1);
but sadly, that won't work. However, if you're driving the process with PHP, that's pretty easy to work around.
Write a script to run as a cron job to:
Dump the archive data from the "live" table (this is probably more efficient using mysqldump from a shell script)
Truncate the live table
Modify the INSERT statements in the dump file so that the table name references the archive table instead of the live table
Append the archive data to the archive table (again, could just import from dump file via shell script, e.g. mysql dbname < dumpfile.sql)
This would depend on what you're doing with the data once you've archived it, but have you considered using MySQL replication?
You could set up another server as a replication slave, and once all the data gets replicated, do your delete or truncate with a SET BIN-LOG 0 before it to avoid that statement also being replicated.

Categories