FDW insert 接口调用

目录

 

研究方法

GDB跟踪

断点设置

单条插入

多条插入

FDW写入接口说明

接口调用顺序

FDW insert接口实现考量 


研究fdw insert接口调用,找到哪些接口被调用,以及它们的调用时机,作用,参数。在了解这些之后,可以考虑自己实现FDW接口函数,接入到其他数据库。

后面的函数说明并没有完全照搬官方文档,按照自己的理解写出来的,所以会有理解错误,欢迎指正。

研究方法

GDB跟踪 + 源码 + 官方文档

设置postgre_fdw所有接口实现函数为断点,执行单条插入和多条插入,获得接口调用流程。

后面堆栈查看和代码阅读等略过。

GDB跟踪

断点设置

Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 1 (postgresGetForeignRelSize) pending.
(gdb) b postgresGetForeignPaths
Function "postgresGetForeignPaths" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (postgresGetForeignPaths) pending.
(gdb) b postgresGetForeignPlan
Function "postgresGetForeignPlan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 3 (postgresGetForeignPlan) pending.
(gdb) b postgresBeginForeignScan
Function "postgresBeginForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 4 (postgresBeginForeignScan) pending.
(gdb) b postgresIterateForeignScan
Function "postgresIterateForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 5 (postgresIterateForeignScan) pending.
(gdb) b postgresReScanForeignScan
Function "postgresReScanForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 6 (postgresReScanForeignScan) pending.
(gdb) b postgresEndForeignScan
Function "postgresEndForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 7 (postgresEndForeignScan) pending.
(gdb) b postgresAddForeignUpdateTargets
Function "postgresAddForeignUpdateTargets" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 8 (postgresAddForeignUpdateTargets) pending.
(gdb) b postgresPlanForeignModify
Function "postgresPlanForeignModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 9 (postgresPlanForeignModify) pending.
(gdb) b postgresBeginForeignModify
Function "postgresBeginForeignModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 10 (postgresBeginForeignModify) pending.
(gdb) b postgresExecForeignInsert
Function "postgresExecForeignInsert" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 11 (postgresExecForeignInsert) pending.
(gdb) b postgresExecForeignUpdate
Function "postgresExecForeignUpdate" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 12 (postgresExecForeignUpdate) pending.
(gdb) b postgresExecForeignDelete
Function "postgresExecForeignDelete" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 13 (postgresExecForeignDelete) pending.
(gdb) b postgresEndForeignModify
Function "postgresEndForeignModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 14 (postgresEndForeignModify) pending.
(gdb) b postgresIsForeignRelUpdatable
Function "postgresIsForeignRelUpdatable" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 15 (postgresIsForeignRelUpdatable) pending.
(gdb) b postgresPlanDirectModify
Function "postgresPlanDirectModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 16 (postgresPlanDirectModify) pending.
(gdb) b postgresBeginDirectModify
Function "postgresBeginDirectModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 17 (postgresBeginDirectModify) pending.
(gdb) b postgresIterateDirectModify
Function "postgresIterateDirectModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 18 (postgresIterateDirectModify) pending.
(gdb) b postgresEndDirectModify
Function "postgresEndDirectModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 19 (postgresEndDirectModify) pending.
(gdb) b postgresRecheckForeignScan
Function "postgresRecheckForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 20 (postgresRecheckForeignScan) pending.
(gdb) b postgresExplainForeignScan
Function "postgresExplainForeignScan" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 21 (postgresExplainForeignScan) pending.
(gdb) b postgresExplainForeignModify
Function "postgresExplainForeignModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 22 (postgresExplainForeignModify) pending.
(gdb) b postgresExplainDirectModify
Function "postgresExplainDirectModify" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 23 (postgresExplainDirectModify) pending.
(gdb) b postgresAnalyzeForeignTable
Function "postgresAnalyzeForeignTable" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 24 (postgresAnalyzeForeignTable) pending.
(gdb) b postgresImportForeignSchema
Function "postgresImportForeignSchema" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 25 (postgresImportForeignSchema) pending.
(gdb) b postgresGetForeignJoinPaths
Function "postgresGetForeignJoinPaths" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 26 (postgresGetForeignJoinPaths) pending.
(gdb) b postgresGetForeignUpperPaths
Function "postgresGetForeignUpperPaths" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

单条插入

postgres=# \d+ xxfdw
                                      Foreign table "public.xxfdw"
 Column |  Type   | Collation | Nullable | Default | FDW options | Storage  | Stats target | Description 
--------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
 id     | integer |           |          |         |             | plain    |              | 
 name   | text    |           |          |         |             | extended |              | 
Server: server127
FDW options: (schema_name 'public', table_name 'xx')

insert into xxfdw values (20, 'abc');


Breakpoint 16, 0x00007f0fc8966fa0 in postgresPlanDirectModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 9, 0x00007f0fc8967630 in postgresPlanForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 15, 0x00007f0fc89655f0 in postgresIsForeignRelUpdatable () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 10, 0x00007f0fc8967370 in postgresBeginForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 11, 0x00007f0fc89693b0 in postgresExecForeignInsert () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 14, 0x00007f0fc8965960 in postgresEndForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

多条插入

用JDBC实现多条插入,源码如下

	public void loadDataPGfdw(int seq) throws SQLException {
		Connection conn = null;
		try {
			url = "jdbc:postgresql://192.168.55.60:5432/postgres";
			usr = "postgres";
			psd = "postgres";
			Class.forName("org.postgresql.Driver");
			System.out.println("Write to PG fdw");
	        conn = DriverManager.getConnection(url, usr, psd);
	        conn.setAutoCommit(false);
	        Statement st = conn.createStatement();
	        String table = "xxfdw";
	        String sql = "insert into " + table+ "(id, name) values(?,?)";
	        Date startTime = new Date();
			
			try(PreparedStatement  pStatement = conn.prepareStatement(sql);) {			
				int rows = 0;
				int batchCount = 0;
				while(rows++ < 10) {
					//写一行
					pStatement.setInt(1, rows);
					total_bytes += 4;
					pStatement.setInt(1, rows);
					pStatement.setString(2, "a");
					pStatement.addBatch();
					batchCount++;
					//批量提交
					if (batchCount== 10) {
						Thread.sleep(1000*30);
						pStatement.executeBatch();
						conn.commit();
						batchCount = 0;
						System.out.println("commit batch");
					}
				}
				if (batchCount>0) {
					pStatement.executeBatch();
				}
			    st.close();
		        conn.close();
			}
			Date endTime = new Date();
			System.out.printf("Insert complete, interval=%d\n", endTime.getTime() - startTime.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(conn != null) {
				
				conn.close();
			}
		}
	}

断点跟踪,循环执行这6个接口,完成多行插入。

Breakpoint 27 (postgresGetForeignUpperPaths) pending.
(gdb) c
Continuing.

Breakpoint 16, 0x00007f0fc8966fa0 in postgresPlanDirectModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 9, 0x00007f0fc8967630 in postgresPlanForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 15, 0x00007f0fc89655f0 in postgresIsForeignRelUpdatable () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 10, 0x00007f0fc8967370 in postgresBeginForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 11, 0x00007f0fc89693b0 in postgresExecForeignInsert () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 14, 0x00007f0fc8965960 in postgresEndForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 16, 0x00007f0fc8966fa0 in postgresPlanDirectModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 9, 0x00007f0fc8967630 in postgresPlanForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 15, 0x00007f0fc89655f0 in postgresIsForeignRelUpdatable () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 10, 0x00007f0fc8967370 in postgresBeginForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 11, 0x00007f0fc89693b0 in postgresExecForeignInsert () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 14, 0x00007f0fc8965960 in postgresEndForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 16, 0x00007f0fc8966fa0 in postgresPlanDirectModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 9, 0x00007f0fc8967630 in postgresPlanForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 15, 0x00007f0fc89655f0 in postgresIsForeignRelUpdatable () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 10, 0x00007f0fc8967370 in postgresBeginForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 11, 0x00007f0fc89693b0 in postgresExecForeignInsert () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 14, 0x00007f0fc8965960 in postgresEndForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 16, 0x00007f0fc8966fa0 in postgresPlanDirectModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 9, 0x00007f0fc8967630 in postgresPlanForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 15, 0x00007f0fc89655f0 in postgresIsForeignRelUpdatable () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 10, 0x00007f0fc8967370 in postgresBeginForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 11, 0x00007f0fc89693b0 in postgresExecForeignInsert () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

Breakpoint 14, 0x00007f0fc8965960 in postgresEndForeignModify () from /usr/local/postgresql/lib/postgres_fdw.so
(gdb) c
Continuing.

...

FDW写入接口说明

接口调用顺序

PlanDirectModify、PlanForeignModify在生成计划树时调用

后4个接口在执行计划树时调用

在Batch insert的时候,每一行都是按照这个顺序6个接口依次执行

在实际接口实现时,外部数据库连接只在BeginForeignModify 中创建一次,再不关闭,保持长连接。后续的执行不需要重新建立连接。

也就是说,在接下来的insert操作中,只有ExecForeignInsert会访问外部数据库,其他接口都属于内部操作。

FDW insert接口实现考量 

PlanDirectModify,  不需要实现,只需要返回false即可。因为这个只针对update和delete.

PlanForeignModify, 需要针对对外部表的目标重写sql语句,记录insert 列的属性

IsForeignRelUpdatable,  设定可insert即可。

BeginForeignModify,  这里要实现对外部数据库的连接;申请资源;

ExecForeignInsert,     实现对外部数据库表的插入

EndForeignModify,     释放在BeginForignModify和ExecForeignInsert中申请的资源

猜你喜欢

转载自blog.csdn.net/jacicson1987/article/details/82855217
今日推荐