暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

opengauss-libpq多host地址链接配置及测试方法

原创 qi_yu 2024-06-17
294

1. libpq 对应驱动包

解压到指定目录,以 解压到/gauss/software/libpq305为例

2.配置连接串

dbname=数据库名 port=端囗号 host='ip1,ip2' user='用户名' password='密码' 参数 1=xxx 参数 2=xxx 参数 3=xxx

示例

conninfo="dbname=postgres port=26000,26000
host='172.198.194.194,172.198.194.195'user='test'
password='startinit123.' application name=testconnect timeout=5 sslmode=allow "

3.编译 libpq 可执行程序

以c程序为例

3.1 编译工具

gcc

3.2 编译方法

gcc -o test libpg-test.c -l /gauss/software/libpq305/include -L /gauss/software/libpq305/lib -lpq

3.3 加参数执行程序

./test
postgres://user:password@ipl:port,ip2:port/dbname?target_sessionattrs=read-write

例:

./test
postgres://test:startinitt123.@172.198.194.194:26000,172.198.194.195:26000/postgres?target session attrs=read-write
或
./test(程序里已经配置好连接串)

注意:字符串开关 postgres 与 postgresql 无差别

注意:用户的密码中如何包含特殊字符,例如!#,需要用反斜杠做转义。因为!#在 linux 中有特殊含义,否则密码不识别。

参数说明:
target_session_attrs=any : libpq 不会刻意去连接主机,而是按照ip 顺序连接
target_session_attrs=read-write: libpq 会自动连接可读写的主库

4. 测试程序

#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"
static void
exit nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}

int
main(int argc, char **argv)
{
    const char *conninfo;
    PGconn *conn;
    PGresult *res;
    int nFields;
    int i,
        j;
    /*
    *如果用户在命令行上提供了一个参数,将它用作连接信息串。
    *否则默认用设置 dbname=postgres 并且为所有其他链接参数使用环境变量或默认值。
    */
    if (argc > 1)
        conninfo = argv[1];
    else
        conninfo ="dbname=postgres port=26000 host='172.198.194.194,172.198.194.195' application_name=test connect_timeout=5 sslmode=allow user='test' password='startinitt123.'";

    /* 建立到数据库的一个连接 */
    conn= PQconnectdb(conninfo);

    /* 检查看后端连接是否成功建立 */
    if (PQstatus(conn)!= CONNECTION OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
                 PQerrorMessage(conn));
        exit_nicely(conn);
    /* 设置总是安全的搜索路径,这样恶意用户就无法取得控制。 */
    res = PQexec(conn,
                "SELECT pg_catalog.set_config('search_path', ", false)");
    if (PQresultStatus(res)!=PGRES_TUPLES_OK)
    {
        fprintf(stderr, "SET failed: %s",PQerrorMessage(conn));
        PQclear(res);
        exit nicely(conn);
    }
    /*
      *任何时候不再需要 PGresult 时,应该 PQclear 它来避免内存泄露
    */
    PQclear(res);
    /*
    *创建一个测试表结构
    */
    res = PQexec(conn, "CREATE TABLE TEST_LIB(id INT,name VARCHAR)");
    if (PQresultStatus(res)!= PGRES_COMMAND_OK)
    {
        fprintf(stderr, "CREATE TABLE TEST_LIB failed:%s",PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);
    /*
    *我们的测试案例这里涉及使用一个游标,对它我们必须用在一个事务块内。
    *我们可以在一个单一的"select * from test"的PQexec()中做整个事情,
    *但是作为一个好的例子它太琐碎
    */
    /*开始一个事务块 */
    res = PQexec(conn, "BEGIN");
    if (PQresultStatus(res)!= PGRES COMMAND OK)
    {
        fprintf(stderr, "BEGIN command failed: %s",PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);

    res = PQexec(conn, "INSERT INTO TEST_LIB VALUES(1,'test_username')");
    if (PQresultStatus(res)!= PGRES_COMMAND_OK)
    {
        fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
        PQclear(res);
        exit nicely(conn);
    }
    PQclear(res);
    res = PQexec(conn, "INSERT INTO TEST_LIB VALUES(2,'aaaaaaaaaa')");
    if (PQresultStatus(res)!= PGRES COMMAND OK)
    {
        fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
        PQclear(res);
        exit nicely(conn);
    }
    PQclear(res);

    res = PQexec(conn, "SELECT * FROM TEST_LIB");
    if (PQresultStatus(res)!=PGRES TUPLES OK)
    {
        fprintf(stderr, "SELECT TABLE TEST_LIB failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit nicely(conn);
    }
    /*首先,打印出属性名 */
    nFields = Panfields(res);
    for (i=0; i< nFields;i++)
        printf("%-15s", PQfname(res, i));
    printf("\n\n");
    /~接下来,打印出行 */
    for (i = 0; i< PQntuples(res); i++)
    {
        for (j= 0; j< nFields; j++)
            printf("%-15s", PQgetvalue(res, i, j));
        printf("\n");
    }

    PQclear(res);

    printf("-------------------------------\n");
    res = PQexec(conn, "UPDATE TEST_LIB SET name='mike' WHERE id=2");
    if (PQresultStatus(res)!= PGRES_COMMAND_OK)
    {
    fprintf(stderr, "INSERT INTO TEST_LIB failed: %s",PQerrorMessage(conn));
    PQclear(res);
    exit nicely(conn);
    }
    PQclear(res);

    res = PQexec(conn, "SELECT * FROM TEST_LIB");
    if (PQresultStatus(res)!= PGRES_TUPLES_OK)
    {
        fprintf(stderr, "SELECT TABLE TEST_LIB failed:%s",PQerrorMessage(conn));
        PQclear(res);
        exit nicely(conn);
    }

    /*首先,打印出属性名 */
    nFields = PQnfields(res);
    for (i= 0;i< nFields;i++)
        printf("%-15s", PQfname(res, i));
    printf("\n\n");
    /*接下来,打印出行 */
    for (i = 0;i< PQntuples(res); i++)
    {
        for (j= 0; j< nFields; j++)
            printf("%-15s", PQgetvalue(res, i, j));
        printf("\n");
    }

    PQclear(res);

    /*删除表以便下回运行,创建表 TEST */
    res = PQexec(conn, "DROP TABLE TEST_LIB");
    PQclear(res);

    /*结束事务 */
    res = PQexec(conn, "END");
    PQclear(res);

    /*关闭到数据库的连接并且清理 */
    PQfinish(conn);
    return 0;
}
最后修改时间:2024-06-18 15:33:37
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论