云服务器内容精选
-
示例 逻辑复制类PGReplicationStream为非线程安全类,并发调用可能导致数据异常。 代码运行的前提条件: 添加JDBC用户机器IP(假设IP为10.11.12.34)到复制数据权限的白名单里,命令如下: gs_guc reload -Z datanode -N all -I all -h 'host replication all 10.11.12.34/32 sha256' 将wal_level参数设置为logical,设置方法请联系管理员处理。 创建表t1和t2,并且对该表进行DDL或DML操作。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 // 以下用例以opengaussjdbc.jar为例。 // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放,使用时解密),确保安全。 // 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 // $ip、$port、database需要用户自行修改。 import com.huawei.opengauss.jdbc.PGProperty; import com.huawei.opengauss.jdbc.jdbc.PgConnection; import com.huawei.opengauss.jdbc.replication.LogSequenceNumber; import com.huawei.opengauss.jdbc.replication.PGReplicationStream; import java.nio.ByteBuffer; import java.sql.DriverManager; import java.util.Properties; import java.util.concurrent.TimeUnit; public class LogicalReplicationDemo { private static PgConnection conn = null; public static void main(String[] args) { String driver = "com.huawei.opengauss.jdbc.Driver"; // 此处配置数据库IP以及端口,这里的端口为haPort,通常默认是所连接DN的port+1端口 String sourceURL = "jdbc:opengauss://$ip:$port/database"; // 默认逻辑复制槽的名称是:replication_slot // 测试模式:创建逻辑复制槽 int TEST_MODE_CREATE_SLOT = 1; // 测试模式:开启逻辑复制(前提条件是逻辑复制槽已经存在) int TEST_MODE_START_REPL = 2; // 测试模式:删除逻辑复制槽 int TEST_MODE_DROP_SLOT = 3; // 开启不同的测试模式 int testMode = TEST_MODE_START_REPL; try { Class.forName(driver); } catch (Exception e) { e.printStackTrace(); return; } try { Properties properties = new Properties(); PGProperty.USER.set(properties, System.getenv("EXAMPLE_USERNAME_ENV")); PGProperty.PASSWORD.set(properties, System.getenv("EXAMPLE_PASSWORD_ENV")); // 对于逻辑复制,以下三个属性是必须配置项 PGProperty.ASSUME_MIN_SERVER_VERSION.set(properties, "9.4"); PGProperty.REPLICATION.set(properties, "database"); PGProperty.PREFER_QUERY_MODE.set(properties, "simple"); conn = (PgConnection) DriverManager.getConnection(sourceURL, properties); System.out.println("connection success!"); if(testMode == TEST_MODE_CREATE_SLOT){ conn.getReplicationAPI() .createReplicationSlot() .logical() .withSlotName("replication_slot") // 这里字符串如包含大写字母则会自动转化为小写字母 .withOutputPlugin("mppdb_decoding") .make(); }else if(testMode == TEST_MODE_START_REPL) { // 开启此模式前需要创建复制槽 LogSequenceNumber waitLSN = LogSequenceNumber.valueOf("6F/E3C53568"); // LSN需要用户根据实际情况进行修改 PGReplicationStream stream = conn .getReplicationAPI() .replicationStream() .logical() .withSlotName("replication_slot") .withSlotOption("include-xids", true) .withSlotOption("skip-empty-xacts", true) .withStartPosition(waitLSN) .withSlotOption("parallel-decode-num", 10) // 解码线程并行度 .withSlotOption("white-table-list", "public.t1,public.t2") // 白名单列表 // .withSlotOption("standby-connection", true) // 强制备机解码 .withSlotOption("decode-style", "t") // 解码格式 .withSlotOption("sending-batch", 0) // 批量发送解码结果 .withSlotOption("max-txn-in-memory", 100) // 单个解码事务落盘内存阈值为100MB .withSlotOption("max-reorderbuffer-in-memory", 2) // 正在处理的解码事务落盘内存阈值为2GB .withSlotOption("exclude-users", "userA") // 不返回用户userA执行事务的逻辑日志 .withSlotOption("include-user", false) // 事务BEGIN逻辑日志不携带用户名 .withSlotOption("enable-heartbeat", true) // 开启心跳日志 .start(); while (true) { ByteBuffer byteBuffer = stream.readPending(); if (byteBuffer == null) { TimeUnit.MILLISECONDS.sleep(10L); continue; } int offset = byteBuffer.arrayOffset(); byte[] source = byteBuffer.array(); int length = source.length - offset; System.out.println(new String(source, offset, length)); // 如果需要flush lsn,根据业务实际情况调用以下接口,该接口会触发数据库复制槽落盘,对服务端解码性能有一定影响,建议调用间隔大于10s。 // LogSequenceNumber lastRecv = stream.getLastReceiveLSN(); // stream.setFlushedLSN(lastRecv); // stream.forceUpdateStatus(); } }else if(testMode == TEST_MODE_DROP_SLOT){ conn.getReplicationAPI() .dropReplicationSlot("replication_slot"); } } catch (Exception e) { e.printStackTrace(); return; } finally { try { conn.close(); } catch (Exception e) { e.printStackTrace(); } } } } text格式(即't'格式)解码结果示例如下: BEGIN CS N: 2014 first_lsn: 0/2816A28 table public t1 INSERT: a[integer]:1 b[integer]:2 c[text]:'hello' COMMIT XID: 15504 BEGIN CSN: 2015 first_lsn: 0/2816C20 table public t1 UPDATE: old-key: a[integer]:1 b[integer]:2 c[text]:'hello' new-tuple: a[integer]:1 b[integer]:5 c[text]:'hello' COMMIT XID: 15505 BEGIN CSN: 2016 first_lsn: 0/2816D60 table public t1 DELETE: a[integer]:1 b[integer]:5 c[text]:'hello' COMMIT XID: 15506 json格式(即'j'格式)解码结果示例如下: BEGIN CSN: 2014 first_lsn: 0/2816A28 {"table_name":"public.t1","op_type":"INSERT","columns_name":["a","b","c"],"columns_type":["integer","integer","text"],"columns_val":["1","2","'hello'"],"old_keys_name":[],"old_keys_type":[],"old_keys_val":[]} COMMIT XID: 15504 BEGIN CSN: 2015 first_lsn: 0/2816C20 {"table_name":"public.t1","op_type":"UPDATE","columns_name":["a","b","c"],"columns_type":["integer","integer","text"],"columns_val":["1","5","'hello'"],"old_keys_name":["a","b","c"],"old_keys_type":["integer","integer","text"],"old_keys_val":["1","2","'hello'"]} COMMIT XID: 15505 BEGIN CSN: 2016 first_lsn: 0/2816D60 {"table_name":"public.t1","op_type":"DELETE","columns_name":[],"columns_type":[],"columns_val":[],"old_keys_name":["a","b","c"],"old_keys_type":["integer","integer","text"],"old_keys_val":["1","5","'hello'"]} COMMIT XID: 15506
-
日志诊断场景 ODBC日志分为unixODBC驱动管理器日志和psqlODBC驱动端日志。前者可以用于追溯应用程序API的执行是否成功,后者是底层实现过程中的一些DFX日志,用来帮助定位问题。 unixODBC日志需要在odbcinst.ini文件中配置: 1 2 3 4 5 6 7 [ODBC] Trace=Yes TraceFile=/path/to/odbctrace.log [GaussMPP] Driver64=/usr/local/lib/psqlodbcw.so setup=/usr/local/lib/psqlodbcw.so psqlODBC日志只需要在odbc.ini加上: [gaussdb] Driver=GaussMPP Servername=10.10.0.13(数据库Server IP) ... Debug=1(打开驱动端debug日志) unixODBC日志将会生成在TraceFile配置的路径下,psqlODBC会在系统/tmp/下生成mylog_xxx.log。
-
创建和调用存储过程 此示例将演示如何基于 GaussDB 提供的JDBC接口开发应用程序。本示例演示如何连接数据库、创建和调用存储过程。 代码运行的前提条件:根据实际情况添加opengaussjdbc.jar包(例如用户使用IDE执行代码,则需要在本地IDE添加opengaussjdbc.jar包)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放,使用时解密),确保安全; // 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 // $ip、$port、database需要用户自行修改。 import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.sql.CallableStatement; import java.sql.Types; public class DBTest { //以非加密方式创建数据库连接。 public static Connection GetConnection(String username, String passwd) { String driver = "com.huawei.opengauss.jdbc.Driver"; String sourceURL = "jdbc:opengauss://$ip:$port/database"; Connection conn = null; try { //加载数据库驱动。 Class.forName(driver).newInstance(); } catch (Exception e) { e.printStackTrace(); return null; } try { //创建数据库连接。 conn = DriverManager.getConnection(sourceURL, username, passwd); System.out.println("Connection succeed!"); } catch (Exception e) { e.printStackTrace(); return null; } return conn; }; // 创建存储过程。 public static void CreateCallable(Connection conn) { Statement stmt = null; try { stmt = conn.createStatement(); // 创建存储过程,返回三个输入值的和。 stmt.execute("create or replace procedure testproc \n" + "(\n" + " psv_in1 in integer,\n" + " psv_in2 in integer,\n" + " psv_inout inout integer\n" + ")\n" + "as\n" + "begin\n" + " psv_inout := psv_in1 + psv_in2 + psv_inout;\n" + "end;\n" + "/"); } catch (SQLException e) { throw new RuntimeException(e); } finally { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } } //调用存储过程。 public static void ExecCallableSQL(Connection conn) { CallableStatement cstmt = null; try { cstmt=conn.prepareCall("{? = CALL TESTPROC(?,?,?)}"); cstmt.setInt(2, 50); cstmt.setInt(1, 20); cstmt.setInt(3, 90); cstmt.registerOutParameter(4, Types.INTEGER); //注册out类型的参数,类型为整型。 cstmt.execute(); int out = cstmt.getInt(4); //获取out参数 System.out.println("The CallableStatment TESTPROC returns:"+out); cstmt.close(); } catch (SQLException e) { if (cstmt != null) { try { cstmt.close(); } catch (SQLException e1) { e1.printStackTrace(); } } e.printStackTrace(); } } /** * 主程序,逐步调用各静态方法。 * @param args */ public static void main(String[] args) { //创建数据库连接。 String userName = System.getenv("EXAMPLE_USERNAME_ENV"); String password = System.getenv("EXAMPLE_PASSWORD_ENV"); Connection conn = GetConnection(userName, password); // 创建存储过程。 CreateCallable(conn); //执行存储过程。 ExecCallableSQL(conn); //关闭数据库连接。 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } 上述示例的运行结果为: Connection succeed! The CallableStatment TESTPROC returns:160 父主题: 典型应用开发示例
-
获取函数返回值 JDBC调用函数时获取返回值,以下示例展示返回值类型为bit和float8两种数据类型,其他数据类型可参考本示例。 代码运行的前提条件:根据实际情况添加opengaussjdbc.jar包(例如用户使用IDE执行代码,则需要在本地IDE添加opengaussjdbc.jar包)。 // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放,使用时解密),确保安全。 // 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。 // $ip、$port、database需要用户自行修改。 import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; import java.sql.CallableStatement; import java.sql.SQLException; import java.sql.PreparedStatement; import java.sql.Types; public class Type { public static void main(String[] args) throws SQLException { String driver = "com.huawei.opengauss.jdbc.Driver"; String username = System.getenv("EXAMPLE_USERNAME_ENV"); String passwd = System.getenv("EXAMPLE_PASSWORD_ENV"); String sourceURL = "jdbc:opengauss://$ip:$port/database"; Connection conn = null; try { // 加载数据库驱动。 Class.forName(driver).newInstance(); } catch (Exception e) { e.printStackTrace(); } try { // 以非加密方式创建数据库连接。 conn = DriverManager.getConnection(sourceURL, username, passwd); System.out.println("Connection succeed!"); } catch (Exception e) { e.printStackTrace(); } // 建表。 String createsql = "create table if not exists t_bit(col_bit bit)"; Statement stmt = conn.createStatement(); stmt.execute(createsql); stmt.close(); // bit类型使用示例,注意此处bit类型取值范围[0,1]。 Statement st = conn.createStatement(); String sqlstr = "create or replace function fun_1()\n" + "returns bit AS $$\n" + "select col_bit from t_bit limit 1;\n" + "$$\n" + "LANGUAGE SQL;"; st.execute(sqlstr); CallableStatement c = conn.prepareCall("{ ? = call fun_1() }"); // 注册输出类型,位串类型。 c.registerOutParameter(1, Types.BIT); c.execute(); // 使用Boolean类型获取结果。 System.out.println(c.getBoolean(1)); // float8类型使用示例。 st.execute("create table if not exists t_float(col1 float8)"); PreparedStatement pstm = conn.prepareStatement("insert into t_float values(?)"); pstm.setDouble(1, 123456.123); pstm.execute(); pstm.close(); // 函数返回值为float8的使用示例。 st.execute( "create or replace function func_float() " + "return float8 " + "as declare " + "var1 float8; " + "begin " + " select col1 into var1 from t_float limit 1; " + " return var1; " + "end;"); CallableStatement cs = conn.prepareCall("{? = call func_float()}"); cs.registerOutParameter(1, Types.DOUBLE); cs.execute(); System.out.println(cs.getDouble(1)); st.close(); // 关闭数据库连接。 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } 上述示例的运行结果为: Connection succeed! false 123456.123 当前JDBC不支持调用返回数据类型为money的存储过程和函数。 父主题: 典型应用开发示例
-
自动寻主场景 某客户存在一套集中式数据库实例,包含1主2备三个节点{node1,node2,node3},其中node1为主节点,node2、node3为备节点。 客户希望应用连接能建立在主DN上,并在发生主备切换时,自动选择新的主节点建连,则url可参考如下配置: jdbc:opengauss://node1,node2,node3/database?targetServerType=master
-
高性能场景 某客户对于相同sql可能多次执行,仅是传参不同,为了提升执行效率,可开启prepareThreshold参数,避免重复生成执行计划,url可参考如下配置。 jdbc:opengauss://node1/database?prepareThreshold=5 某客户一次查询1000万数据,为避免同时返回造成内存溢出,可使用defaultRowFetchSize,url可参考如下配置。 jdbc:opengauss://node1/database?defaultRowFetchSize=50000 某客户需要批量插入1000万数据,为提升效率,可使用batchMode,url可参考如下配置。 jdbc:opengauss://node1/database?batchMode=on
-
容灾场景 某客户有两套数据库实例,其中A数据库实例为生产数据库实例,B数据库实例为容灾数据库实例。当客户执行容灾切换时,A数据库实例将降为容灾数据库实例,B数据库实例将升为生产数据库实例。此时为了避免修改配置文件导致的应用重启或重新发版。客户可在初始配置文件时,即将A、B数据库实例写入连接串中。此时在主数据库实例不可连接时,驱动将尝试对容灾数据库实例建连。例如A数据库实例为{node1,node2,node3}。B数据库实例为{node4,node5,node6}。 则url可参考如下进行配置: jdbc:opengauss://node1,node2,node3,node4,node5,node6/database?priorityServers=3
-
获取函数返回值 JDBC调用函数时获取返回值,以下示例展示返回值类型为bit和float8两种数据类型,其他数据类型可参考本示例。 代码运行的前提条件:根据实际情况添加gaussdbjdbc.jar包(例如用户使用IDE执行代码,则需要在本地IDE添加gaussdbjdbc.jar包)。 // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放,使用时解密),确保安全。// 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。// $ip、$port、database需要用户自行修改。import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;import java.sql.CallableStatement;import java.sql.SQLException;import java.sql.PreparedStatement;import java.sql.Types;public class Type { public static void main(String[] args) throws SQLException { String driver = "com.huawei.gaussdb.jdbc.Driver"; String username = System.getenv("EXAMPLE_USERNAME_ENV"); String passwd = System.getenv("EXAMPLE_PASSWORD_ENV"); String sourceURL = "jdbc:gaussdb://$ip:$port/database"; Connection conn = null; try { // 加载数据库驱动。 Class.forName(driver).newInstance(); } catch (Exception e) { e.printStackTrace(); } try { // 以非加密方式创建数据库连接。 conn = DriverManager.getConnection(sourceURL, username, passwd); System.out.println("Connection succeed!"); } catch (Exception e) { e.printStackTrace(); } // 建表。 String createsql = "create table if not exists t_bit(col_bit bit)"; Statement stmt = conn.createStatement(); stmt.execute(createsql); stmt.close(); // bit类型使用示例,注意此处bit类型取值范围[0,1]。 Statement st = conn.createStatement(); String sqlstr = "create or replace function fun_1()\n" + "returns bit AS $$\n" + "select col_bit from t_bit limit 1;\n" + "$$\n" + "LANGUAGE SQL;"; st.execute(sqlstr); CallableStatement c = conn.prepareCall("{ ? = call fun_1() }"); // 注册输出类型,位串类型。 c.registerOutParameter(1, Types.BIT); c.execute(); // 使用Boolean类型获取结果。 System.out.println(c.getBoolean(1)); // float8类型使用示例。 st.execute("create table if not exists t_float(col1 float8)"); PreparedStatement pstm = conn.prepareStatement("insert into t_float values(?)"); pstm.setDouble(1, 123456.123); pstm.execute(); pstm.close(); // 函数返回值为float8的使用示例。 st.execute( "create or replace function func_float() " + "return float8 " + "as declare " + "var1 float8; " + "begin " + " select col1 into var1 from t_float limit 1; " + " return var1; " + "end;"); CallableStatement cs = conn.prepareCall("{? = call func_float()}"); cs.registerOutParameter(1, Types.DOUBLE); cs.execute(); System.out.println(cs.getDouble(1)); st.close(); // 关闭数据库连接。 try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } }} 上述示例的运行结果为: Connection succeed!false123456.123 父主题: 典型应用开发示例
更多精彩内容
CDN加速
GaussDB
文字转换成语音
免费的服务器
如何创建网站
域名网站购买
私有云桌面
云主机哪个好
域名怎么备案
手机云电脑
SSL证书申请
云点播服务器
免费OCR是什么
电脑云桌面
域名备案怎么弄
语音转文字
文字图片识别
云桌面是什么
网址安全检测
网站建设搭建
国外CDN加速
SSL免费证书申请
短信批量发送
图片OCR识别
云数据库MySQL
个人域名购买
录音转文字
扫描图片识别文字
OCR图片识别
行驶证识别
虚拟电话号码
电话呼叫中心软件
怎么制作一个网站
Email注册网站
华为VNC
图像文字识别
企业网站制作
个人网站搭建
华为云计算
免费租用云托管
云桌面云服务器
ocr文字识别免费版
HTTPS证书申请
图片文字识别转换
国外域名注册商
使用免费虚拟主机
云电脑主机多少钱
鲲鹏云手机
短信验证码平台
OCR图片文字识别
SSL证书是什么
申请企业邮箱步骤
免费的企业用邮箱
云免流搭建教程
域名价格