如何用php实现两个Oracle数据库同步功能?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用php实现两个Oracle数据库同步功能?相关的知识,希望对你有一定的参考价值。

你是希望用php代码实现同时写两个数据库还是希望只是两个数据库的数据一致?如果仅是希望数据库数据数据一至,oracle自带的机制就能实现。如果是想自己编程实现同时两个数据库的操作,也方便,PHP在链接不同数据库实例时,会得到不同的链接句柄,在后面具体操作时,同时对这两个链接句柄操作就行了,但这样存在数据不完全一致的风险,必须校验,这样又拖慢了速度。
演示代码如下:
echo "<br /><b>演示多数据库克隆操作(多数据库同时写操作)</b><br />";
$this->loadModel('student.php',1);
//如果两个不同数据库服务器的表对象结构完全一致,则不必重复载入表对象定义文件,只需要在实例化时指定服务器id就行了。
//$this->loadModel('student.php',2);
$this->loadModel('student2.php',2);
$student1=new Tstudent(1);
$student2=new Tstudent2(2);
$student3=new Tstudent(2);
$student2->cloneFrom($student1);
$student3->cloneFrom($student1);
$student1->uuid='999';
$student1->id='999';
$student1->name='测试克隆人';
//如果进行了主对象的克隆操作,则在完成主对象数据持久化后,所有的子对象将会同步插入数据。
$student1->insert();
参考技术A 同步的数据多吗?是按日同步还是由操作员手动时间同步?
自动同步方式:
两个Oracle实例间的数据同步,如果网络通的话,可以使用DBLink来实现,添加一个Oracle Job,设定多长时间进行同步一次,写个存储过程就可以。
手动同步方式:
可以在表中添加一个状态值,未同步时,设定为0,用户手动同步时(比如点击同步按钮),将此状态改为1,由Job间隔多长时间去读取这个值,如果为1的话,进行同步,同步完毕后,改为2即可。

如果数据量比较小的话就无所谓了,使用JDBC方式同步和DBLink方式没什么区别了追问

是要实现自动同步,数据量也比较大。能不能给出一个更具体一些的方案,或者网上有没有类似的案例啊?

追答

如果数据量比较大的话,就不能使用JDBC方式了。首先要保证两个DB机器间进行可以进行通信

    紧耦合的方式

    在同步的数据库实例中创建 DBLink (用法可以百度一下),这样两个数据库间的表就可以互相访问了,至于同步的方式,就是 select 或者 update 什么的,写个存储过程就OK了。

    松耦合的方式

    这样可以会比较麻烦点(适用于两个机器间不能正常通信的情况下),将源表中的数据导出到文件,然后将文件中传到目标机器上,使用sqlloader进行导入即可。
    有不清楚的可以留下你的联系方式,再沟通

本回答被提问者采纳

如何用python更新mysql数据库数据

MySQL 的 Binlog 记录着 MySQL 数据库的所有变更信息,了解 Binlog 的结构可以帮助我们解析Binlog,甚至对 Binlog 进行一些修改,或者说是“篡改”,例如实现类似于 Oracle 的 flashback 的功能,恢复误删除的记录,把 update 的记录再还原回去等。本文将带您探讨一下这些神奇功能的实现,您会发现比您想象地要简单得多。本文指的 Binlog 是 ROW 模式的 Binlog,这也是 MySQL 8 里的默认模式,STATEMENT 模式因为使用中有很多限制,现在用得越来越少了。
Binlog 由事件(event)组成,请注意是事件(event)不是事务(transaction),一个事务可以包含多个事件。事件描述对数据库的修改内容。
现在我们已经了解了 Binlog 的结构,我们可以试着修改 Binlog 里的数据。例如前面举例的 Binlog 删除了一条记录,我们可以试着把这条记录恢复,Binlog 里面有个删除行(DELETE_ROWS_EVENT)的事件,就是这个事件删除了记录,这个事件和写行(WRITE_ROWS_EVENT)的事件的数据结构是完全一样的,只是删除行事件的类型是 32,写行事件的类型是 30,我们把对应的 Binlog 位置的 32 改成 30 即可把已经删除的记录再插入回去。从前面的 “show binlog events” 里面可看到这个 DELETE_ROWS_EVENT 是从位置 378 开始的,这里的位置就是 Binlog 文件的实际位置(以字节为单位)。从事件(event)的结构里面可以看到 type_code 是在 event 的第 5 个字节,我们写个 Python 小程序把把第383(378+5=383)字节改成 30 即可。当然您也可以用二进制编辑工具来改。
找出 Binlog 中的大事务
由于 ROW 模式的 Binlog 是每一个变更都记录一条日志,因此一个简单的 SQL,在 Binlog 里可能会产生一个巨无霸的事务,例如一个不带 where 的 update 或 delete 语句,修改了全表里面的所有记录,每条记录都在 Binlog 里面记录一次,结果是一个巨大的事务记录。这样的大事务经常是产生麻烦的根源。我的一个客户有一次向我抱怨,一个 Binlog 前滚,滚了两天也没有动静,我把那个 Binlog 解析了一下,发现里面有个事务产生了 1.4G 的记录,修改了 66 万条记录!下面是一个简单的找出 Binlog 中大事务的 Python 小程序,我们知道用 mysqlbinlog 解析的 Binlog,每个事务都是以 BEGIN 开头,以 COMMIT 结束。我们找出 BENGIN 前面的 “# at” 的位置,检查 COMMIT 后面的 “# at” 位置,这两个位置相减即可计算出这个事务的大小,下面是这个 Python 程序的例子。
切割 Binlog 中的大事务
对于大的事务,MySQL 会把它分解成多个事件(注意一个是事务 TRANSACTION,另一个是事件 EVENT),事件的大小由参数 binlog-row-event-max-size 决定,这个参数默认是 8K。因此我们可以把若干个事件切割成一个单独的略小的事务
ROW 模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,这个行为是 binlog_row_image 参数控制的,这个参数有 3 个值,默认为 FULL,也就是记录列的所有修改,即使字段没有发生变更也会记录。这样我们就可以实现类似 Oracle 的 flashback 的功能,我个人估计 MySQL 未来的版本从可能会基于 Binlog 推出这样的功能。
了解了 Binlog 的结构,再加上 Python 这把瑞士军刀,我们还可以实现很多功能,例如我们可以统计哪个表被修改地最多?我们还可以把 Binlog 切割成一段一段的,然后再重组,可以灵活地进行 MySQL 数据库的修改和迁移等工作。
参考技术A mysql> show databases; // 查看当前所有的数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| csvt |
| csvt04 |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.18 sec)

mysql> use test; //作用与test数据库
Database changed
mysql> show tables; //查看test库下面的表
Empty set (0.00 sec)

//创建user表,name 和password 两个字段
mysql> CREATE TABLE user (name VARCHAR(20),password VARCHAR(20)); Query OK, 0 rows affected (0.27 sec)

//向user表内插入若干条数据
mysql> insert into user values('Tom','1321');
Query OK, 1 row affected (0.05 sec)

mysql> insert into user values('Alen','7875');
Query OK, 1 row affected (0.08 sec)

mysql> insert into user values('Jack','7455');
Query OK, 1 row affected (0.04 sec)

//查看user表的数据
mysql> select * from user;
+------+----------+
| name | password |
+------+----------+
| Tom | 1321 |
| Alen | 7875 |
| Jack | 7455 |
+------+----------+
3 rows in set (0.01 sec)

//删除name 等于Jack的数据
mysql> delete from user where name = 'Jack';
Query OK, 1 rows affected (0.06 sec)

//修改name等于Alen 的password 为 1111
mysql> update user set password='1111' where name = 'Alen';
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0

//查看表内容
mysql> select * from user;
+--------+----------+
| name | password |
+--------+----------+
| Tom | 1321 |
| Alen | 1111 |
+--------+----------+
3 rows in set (0.00 sec)

以上是关于如何用php实现两个Oracle数据库同步功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何用wireshark抓取两个路由器之间的数据包

oracle 如何用sql实现split功能

如何用PHP和html做一个附件上传的页面?

如何用Sql语句实现断开使用本数据库的链接的功能?

如何用phpmyadmin导入大容量.sql文件

Day834.Dubbo如何用管程实现异步转同步 -Java 并发编程实战