Feature: allow to specify load balance weight ratio for load balance parameters.
authorBo Peng <pengbo@sraoss.co.jp>
Tue, 7 Aug 2018 01:07:24 +0000 (10:07 +0900)
committerBo Peng <pengbo@sraoss.co.jp>
Tue, 7 Aug 2018 01:07:24 +0000 (10:07 +0900)
Add a new feature to allow to specify load balance weight ratio for
"database_redirect_preference_list" and "app_name_redirect_preference_list"
parameters.

You can specify the list of "database-name:node id(ratio)" pairs to
send SELECT queries to a particular backend node for a particular
database connection at a specified load balance ratio.
Also you can specify list of "application-name:node id(ratio)" pairs to
send SELECT queries to a particular backend node for a particular client
application connection at a specified load balance ratio.

This load balance ratio specifies a value between 0 and 1,
and the default is 1.0.

For example, by specifying "database_redirect_preference_list = 'test:1(0.5)'",
Pgpool-II will redirect 50% SELECT queries to the backend node of ID 1
for the connection to "test" database. And the other 50% SELECT queries
will be sent to other backend nodes.

doc.ja/src/sgml/loadbalance.sgml
doc/src/sgml/loadbalance.sgml
src/include/utils/regex_array.h
src/protocol/child.c
src/test/regression/tests/008.dbredirect/select.pgbench
src/test/regression/tests/008.dbredirect/select1.pgbench [new file with mode: 0644]
src/test/regression/tests/008.dbredirect/test.sh
src/utils/regex_array.c

index 950cdb079f32dd93d92f71490437424d531c9e6f..1b537f6320d4a0b2c83b0be18aa0c43634136891 100644 (file)
@@ -857,14 +857,19 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
          Specifies the list of <replaceable>"database-name:node id"</replaceable> pairs
          to send <acronym>SELECT</acronym> queries to a particular backend
          node for a particular database connection.
+-->
+特定のデータベース接続で<acronym>SELECT</acronym>クエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"<replaceable>データベース名:ノードID(比率)</replaceable>"ペアのリストを指定します。ロードバランス比率は0-1の間の値を指定します。
+比率の指定を省略した場合は、デフォルトの1.0となります。
+        </para>
+        <para>
+<!--
          For example, by specifying "test:1", <productname>Pgpool-II</productname>
          will redirect all <acronym>SELECT</acronym> queries to the backend node of ID 1 for
          the connection to "test" database.
          You can specify multiple <replaceable>"database name:node id"</replaceable> pair by separating them
          using comma (,).
 -->
-特定のデータベース接続では<acronym>SELECT</acronym>クエリが特定のバックエンドノードに送信されるように、"<replaceable>データベース名:ノードID</replaceable>"ペアのリストを指定します。
-たとえば"test:1"とした場合、"test"データベースへの接続においては、<productname>Pgpool-II</productname>は全ての<acronym>SELECT</acronym>クエリをIDが1のバックエンドノードに送信します。
+たとえば"test:1(0.5)"とした場合、"test"データベースへの接続においては、<productname>Pgpool-II</productname>は50%の<acronym>SELECT</acronym>クエリをIDが1のバックエンドノードに送信します。
 複数の"<replaceable>データベース名:ノードID</replaceable>"のペアを カンマ(,)で区切って指定することができます。
         </para>
         <para>
@@ -875,10 +880,10 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
          if <emphasis>"standby"</emphasis> is specified, one of the standby nodes are selected randomly
          based on weights.
 -->
-データベース名には正規表現を指定することできます。
\83\87ã\83¼ã\82¿ã\83\99ã\83¼ã\82¹å\90\8dã\81«ã\81¯æ­£è¦\8f表ç\8f¾ã\82\92æ\8c\87å®\9aã\81\99ã\82\8bã\81\93ã\81¨ã\81\8cã\81§ã\81\8dã\81¾ã\81\99ã\80\82
 <replaceable>ノードID</replaceable>には特別なキーワードを使うことができます。
 "<emphasis>primary</emphasis>"が指定された場合にはクエリはプライマリノードに送られます。
-また、"<emphasis>standby</emphasis>"が指定された場合はスタンバイノードのうちどれかをウェイトに応じてランダムに選択します。
+また、"<emphasis>standby</emphasis>"が指定された場合はスタンバイノードのうちどれかをウェイト(<xref linkend="guc-backend-weight">)に応じてランダムに選択します。
         </para>
 
         <example id="example-database-redirect-list">
@@ -909,7 +914,7 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
                 Route all <acronym>SELECT</acronym> queries on <literal>mydb0</literal> or on
                 <literal>mydb1</literal> databases to backend node of ID 1.
 -->
-全ての<literal>mydb0</literal>または<literal>mydb1</literal>データベースにおける<acronym>SELECT</acronym>クエリはIDが1のバックエンドノードに送る。
+全ての<literal>mydb0</literal>または<literal>mydb1</literal>データベースにおける30%の<acronym>SELECT</acronym>クエリはIDが1のバックエンドノードに送る。
               </para>
             </listitem>
             <listitem>
@@ -929,7 +934,7 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
 -->
 <xref linkend="guc-database-redirect-preference-list">は以下のように設定します。
               <programlisting>
-database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
+database_redirect_preference_list = 'postgres:primary,mydb[01]:1(0.3),mydb2:standby'
               </programlisting>
           </para>
         </example>
@@ -960,7 +965,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
           to send <acronym>SELECT</acronym> queries to a particular backend
           node for a particular client application connection.
 -->
-特定のクライアントアプリケーションの接続では<acronym>SELECT</acronym>クエリが特定のバックエンドノードに送信されるように、"<replaceable>アプリケーション名:ノードID</replaceable>"ペアのリストを指定します。
+特定のクライアントアプリケーションの接続で<acronym>SELECT</acronym>クエリが指定したロードバランス比率で特定のバックエンドノードに送信されるように、"<replaceable>アプリケーション名:ノードID(比率)</replaceable>"ペアのリストを指定します。
         </para>
 
         <note>
@@ -1005,6 +1010,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
 -->
 <xref linkend="guc-app-name-redirect-preference-list">の記法は<xref linkend="guc-database-redirect-preference-list">と同じですので、アプリケーション名には正規表現も使用できます。
 同様に特別なキーワード"<emphasis>primary</emphasis>"はプライマリノードを、"<emphasis>standby</emphasis>"はスタンバイサーバのいずれかを意味します。
+ロードバランス比率は0-1の間の値を指定します。ロードバランス比率の指定を省略した場合は、デフォルトの1.0となります。
         </para>
 
         <example id="example-app-name-redirect-list">
@@ -1035,7 +1041,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
                 Route all <acronym>SELECT</acronym> queries from <literal>myapp1</literal>
                 client to backend node of ID 1.
 -->
-全ての<literal>myapp1</literal>クライアントからの<acronym>SELECT</acronym>クエリはIDが1のバックエンドノードに送る。
+全ての<literal>myapp1</literal>クライアントからの30%の<acronym>SELECT</acronym>クエリはIDが1のバックエンドノードに送る。
               </para>
             </listitem>
             <listitem>
@@ -1055,7 +1061,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
 -->
 <xref linkend="guc-app-name-redirect-preference-list">は以下のように設定します。
               <programlisting>
-app_name_redirect_preference_list = 'psql:primary,myapp1:1,myapp2:standby'
+app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby'
               </programlisting>
           </para>
         </example>
@@ -1068,6 +1074,39 @@ app_name_redirect_preference_list = 'psql:primary,myapp1:1,myapp2:standby'
 -->
 <xref linkend="guc-app-name-redirect-preference-list">は、<xref linkend="guc-database-redirect-preference-list">よりも優先されます。
           </para>
+          <para>
+<!--
+                       For example, if you set
+                       <literal>database_redirect_preference_list = 'postgres:standby(1.0)'</literal> and
+                       <literal>app_name_redirect_preference_list = 'psql:primary(1.0)'</literal>,
+                       all SELECT from psql client on postgres database will be sent to primary backend node.
+-->
+たとえば、
+<literal>database_redirect_preference_list = 'postgres:standby(1.0)'</literal>、
+<literal>app_name_redirect_preference_list = 'myapp1:primary(1.0)'</literal>
+と設定した場合、アプリケーション<literal>myapp1</literal>、<literal>postgres</literal>データベースでの<literal>SELECT</literal>はプライマリバックエンドノードに送られます。
+          </para>
+        </note>
+
+        <note>
+          <para>
+<!--
+                       In the settings of <xref linkend="guc-app-name-redirect-preference-list"> and
+                       <xref linkend="guc-database-redirect-preference-list">, when multiple database
+                       names and application names are matched, the first setting will be used.
+-->
+<xref linkend="guc-app-name-redirect-preference-list">及び<xref linkend="guc-database-redirect-preference-list">の設定では、複数のデータベース名やアプリケーション名にマッチした場合、最初の設定が反映されます。
+          </para>
+          <para>
+<!--
+                       For example, if you set
+                       database_redirect_preference_list = 'postgres:primary,postgres:standby',
+                       "postgres: primary" will be used.
+-->
+たとえば、
+<literal>database_redirect_preference_list = 'postgres:primary,postgres:standby'</literal>
+と設定した場合、<literal>postgres:primary</literal>の設定が反映されます。
+          </para>
         </note>
 
         <caution>
@@ -1081,7 +1120,7 @@ app_name_redirect_preference_list = 'psql:primary,myapp1:1,myapp2:standby'
             If you want to use the <xref linkend="guc-app-name-redirect-preference-list">
             feature through <acronym>JDBC</acronym>, use postgreSQL-9.4 or later version of the driver.
 -->
-<acronym>JDBC</acronym>ドライバのpostgresql-9.3以前のバージョンでは、<acronym>JDBC</acronym>ドライバの"<literal>ApplicationName</literal>" と "<literal>assumeMinServerVersion=9.0</literal>"オプションを指定してもスタートアップパケットの中にアプリケーション名を含ません。
+<acronym>JDBC</acronym>ã\83\89ã\83©ã\82¤ã\83\90ã\81®postgresql-9.3以å\89\8dã\81®ã\83\90ã\83¼ã\82¸ã\83§ã\83³ã\81§ã\81¯ã\80\81<acronym>JDBC</acronym>ã\83\89ã\83©ã\82¤ã\83\90ã\81®"<literal>ApplicationName</literal>" ã\81¨ "<literal>assumeMinServerVersion=9.0</literal>"ã\82ªã\83\97ã\82·ã\83§ã\83³ã\82\92æ\8c\87å®\9aã\81\97ã\81¦ã\82\82ã\82¹ã\82¿ã\83¼ã\83\88ã\82¢ã\83\83ã\83\97ã\83\91ã\82±ã\83\83ã\83\88ã\81®ä¸­ã\81«ã\82¢ã\83\97ã\83ªã\82±ã\83¼ã\82·ã\83§ã\83³å\90\8dã\82\92å\90«ã\81¿ã\81¾ã\81\9bã\82\93ã\80\82
 <acronym>JDBC</acronym>から<xref linkend="guc-app-name-redirect-preference-list">機能を使用したければ、postgresql-9.4 以降のドライバをお使いください
           </para>
         </caution>
index 90a7cb39c17cbc5236bc0040794683cab13d5c28..fb45aa265b2de6238f907b1ec369f60174f40da3 100644 (file)
@@ -656,11 +656,14 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
       </term>
       <listitem>
         <para>
-         Specifies the list of <replaceable>"database-name:node id"</replaceable> pairs
+         Specifies the list of <replaceable>"database-name:node id(ratio)"</replaceable> pairs
          to send <acronym>SELECT</acronym> queries to a particular backend
-         node for a particular database connection.
-         For example, by specifying "test:1", <productname>Pgpool-II</productname>
-         will redirect all <acronym>SELECT</acronym> queries to the backend node of ID 1 for
+         node for a particular database connection at a specified load balance ratio.
+                The load balance ratio specifies a value between 0 and 1. The default is 1.0.
+        </para>
+        <para>
+         For example, by specifying "test:1(0.5)", <productname>Pgpool-II</productname>
+         will redirect 50% <acronym>SELECT</acronym> queries to the backend node of ID 1 for
          the connection to "test" database.
          You can specify multiple <replaceable>"database name:node id"</replaceable> pair by separating them
          using comma (,).
@@ -670,7 +673,7 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
          You can use special keywords as <replaceable>node id</replaceable>.
          If <emphasis>"primary"</emphasis> is specified, queries are sent to the primary node, and
          if <emphasis>"standby"</emphasis> is specified, one of the standby nodes are selected randomly
-         based on weights.
+         based on weights (<xref linkend="guc-backend-weight">).
         </para>
 
         <example id="example-database-redirect-list">
@@ -688,8 +691,9 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
             </listitem>
             <listitem>
               <para>
-                Route all <acronym>SELECT</acronym> queries on <literal>mydb0</literal> or on
-                <literal>mydb1</literal> databases to backend node of ID 1.
+                Route 30% <acronym>SELECT</acronym> queries on <literal>mydb0</literal> or on
+                <literal>mydb1</literal> databases to backend node of ID.
+                               The other 70% <acronym>SELECT</acronym> queries will be sent to other backend nodes.
               </para>
             </listitem>
             <listitem>
@@ -703,7 +707,7 @@ black_query_pattern_list = 'SELECT \* FROM table_name1\;;SELECT col1, col2 FROM
           <para>
             then the <xref linkend="guc-database-redirect-preference-list"> will be configured as follows:
               <programlisting>
-database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
+database_redirect_preference_list = 'postgres:primary,mydb[01]:1(0.3),mydb2:standby'
               </programlisting>
           </para>
         </example>
@@ -723,9 +727,9 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
       <listitem>
 
         <para>
-          Specifies the list of <replaceable>"application-name:node id"</replaceable> pairs
+          Specifies the list of <replaceable>"application-name:node id(ratio)"</replaceable> pairs
           to send <acronym>SELECT</acronym> queries to a particular backend
-          node for a particular client application connection.
+          node for a particular client application connection at a specified load balance ratio.
         </para>
 
         <note>
@@ -737,7 +741,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
 
         <para>
           For example, application name of <command>psql</command> command is
-          <literal>"psql"</literal>
+          <literal>"psql"</literal>.
         </para>
 
         <note>
@@ -756,6 +760,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
           thus you can also use the regular expressions for application names.
           Similarly special keyword <emphasis>"primary"</emphasis> indicates the primary node and
          <emphasis>"standby"</emphasis> indicates one of standby nodes.
+                 The load balance weight specifies a value between 0 and 1. The default is 1.0.
         </para>
 
         <example id="example-app-name-redirect-list">
@@ -773,8 +778,8 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
             </listitem>
             <listitem>
               <para>
-                Route all <acronym>SELECT</acronym> queries from <literal>myapp1</literal>
-                client to backend node of ID 1.
+                Route 30% <acronym>SELECT</acronym> queries from <literal>myapp1</literal>
+                client to backend node of ID 1. The other 70% SELECT queries will be sent to other backend nodes.
               </para>
             </listitem>
             <listitem>
@@ -788,7 +793,7 @@ database_redirect_preference_list = 'postgres:primary,mydb[01]:1,mydb2:standby'
           <para>
             then the <xref linkend="guc-app-name-redirect-preference-list"> will be configured as follows:
               <programlisting>
-app_name_redirect_preference_list = 'psql:primary,myapp1:1,myapp2:standby'
+app_name_redirect_preference_list = 'psql:primary,myapp1:1(0.3),myapp2:standby'
               </programlisting>
           </para>
         </example>
@@ -798,6 +803,25 @@ app_name_redirect_preference_list = 'psql:primary,myapp1:1,myapp2:standby'
             <xref linkend="guc-app-name-redirect-preference-list"> takes precedence
             over the <xref linkend="guc-database-redirect-preference-list">.
           </para>
+          <para>
+                       For example, if you set
+                       <literal>database_redirect_preference_list = 'postgres:standby(1.0)'</literal> and
+                       <literal>app_name_redirect_preference_list = 'myapp1:primary(1.0)'</literal>,
+                       all SELECT from application myapp1 on postgres database will be sent to primary backend node.
+          </para>
+        </note>
+
+        <note>
+          <para>
+                       By specifying of <xref linkend="guc-app-name-redirect-preference-list"> and
+                       <xref linkend="guc-database-redirect-preference-list">, when multiple database
+                       names and application names are matched, the first setting will be used.
+          </para>
+          <para>
+                       For example, if you set
+                       <literal>database_redirect_preference_list = 'postgres:primary,postgres:standby'</literal>,
+                       <literal>"postgres: primary"</literal> will be used.
+          </para>
         </note>
 
         <caution>
index 48768aa5e41fd42e407fca958a60523715519085..3596ca60816a1b0318ebdb32c9ed505c7feefb34 100644 (file)
@@ -46,6 +46,7 @@ void destroy_regex_arrary(RegArray *ar);
 typedef struct {
   char *left_token;
   char *right_token;
+  double weight_token;
 } Left_right_token;
 
 typedef struct {
index 4a970c525077800f7922613b9ceceb2cf2c1bba3..b2669ee5a0ac2a36c4d0d4ff2659037dc6a548e0 100644 (file)
@@ -1666,9 +1666,10 @@ int select_load_balancing_node(void)
        int selected_slot;
        double total_weight,r;
        int i;
-       int index;
+       int index_db = -1, index_app = -1;
        POOL_SESSION_CONTEXT *ses = pool_get_session_context(false);
        int tmp;
+       int no_load_balance_node_id = -2;
 
        /*
         * -2 indicates there's no database_redirect_preference_list. -1 indicates
@@ -1677,7 +1678,13 @@ int select_load_balancing_node(void)
         */
        int suggested_node_id = -2;
 
-       /* 
+#if defined(sun) || defined(__sun)
+       r = (((double)rand())/RAND_MAX);
+#else
+       r = (((double)random())/RAND_MAX);
+#endif
+
+       /*
         * Check database_redirect_preference_list
         */
        if (SL_MODE && pool_config->redirect_dbnames)
@@ -1687,23 +1694,23 @@ int select_load_balancing_node(void)
                /* Check to see if the database matches any of
                 * database_redirect_preference_list
                 */
-               index = regex_array_match(pool_config->redirect_dbnames, database);
-               if (index >= 0)
+               index_db = regex_array_match(pool_config->redirect_dbnames, database);
+               if (index_db >= 0)
                {
                        /* Matches */
                        ereport(DEBUG1,
                                        (errmsg("selecting load balance node db matched"),
-                                        errdetail("dbname: %s index is %d dbnode is %s", database, index, pool_config->db_redirect_tokens->token[index].right_token)));
+                                        errdetail("dbname: %s index is %d dbnode is %s weight is %f", database, index_db,
+                                               pool_config->db_redirect_tokens->token[index_db].right_token,
+                                               pool_config->db_redirect_tokens->token[index_db].weight_token)));
 
-                       tmp = choose_db_node_id(pool_config->db_redirect_tokens->token[index].right_token);
+                       tmp = choose_db_node_id(pool_config->db_redirect_tokens->token[index_db].right_token);
                        if (tmp == -1 || (tmp >= 0 && VALID_BACKEND(tmp)))
-                       {
                                suggested_node_id = tmp;
-                       }
                }
        }
 
-       /* 
+       /*
         * Check app_name_redirect_preference_list
         */
        if (SL_MODE && pool_config->redirect_app_names)
@@ -1716,33 +1723,64 @@ int select_load_balancing_node(void)
                 */
                if (app_name && strlen(app_name) > 0)
                {
-                       /* Check to see if the aplication name matches any of
+                       /*
+                        * Check to see if the aplication name matches any of
                         * app_name_redirect_preference_list.
                         */
-                       index = regex_array_match(pool_config->redirect_app_names, app_name);
-                       if (index >= 0)
+                       index_app = regex_array_match(pool_config->redirect_app_names, app_name);
+                       if (index_app >= 0)
                        {
+
+                               /*
+                                * if the aplication name matches any of app_name_redirect_preference_list,
+                                * database_redirect_preference_list will be ignored.
+                                */
+                               index_db = -1;
+
                                /* Matches */
                                ereport(DEBUG1,
                                                (errmsg("selecting load balance node db matched"),
-                                                errdetail("app_name: %s index is %d dbnode is %s", app_name, index, pool_config->app_name_redirect_tokens->token[index].right_token)));
+                                                errdetail("app_name: %s index is %d dbnode is %s weight is %f", app_name, index_app,
+                                                       pool_config->app_name_redirect_tokens->token[index_app].right_token,
+                                                       pool_config->app_name_redirect_tokens->token[index_app].weight_token)));
 
-                               tmp = choose_db_node_id(pool_config->app_name_redirect_tokens->token[index].right_token);
+                               tmp = choose_db_node_id(pool_config->app_name_redirect_tokens->token[index_app].right_token);
                                if (tmp == -1 || (tmp >= 0 && VALID_BACKEND(tmp)))
-                               {
                                        suggested_node_id = tmp;
-                               }
                        }
                }
        }
 
        if (suggested_node_id >= 0)
        {
-               ereport(DEBUG1,
-                               (errmsg("selecting load balance node"),
-                                errdetail("selected backend id is %d", suggested_node_id)));
+               /*
+                * If the weight is bigger than random rate then send to suggested_node_id.
+                * If the weight is less than random rate then choose load balance node from other nodes.
+                */
+               if ((index_db >= 0 && r <= pool_config->db_redirect_tokens->token[index_db].weight_token) ||
+                       (index_app >= 0 && r <= pool_config->app_name_redirect_tokens->token[index_app].weight_token))
+               {
+                       ereport(DEBUG1,
+                                       (errmsg("selecting load balance node"),
+                                        errdetail("selected backend id is %d", suggested_node_id)));
+                       return suggested_node_id;
+               }
+               else
+                       no_load_balance_node_id = suggested_node_id;
+       }
 
-               return suggested_node_id;
+       /* In case of sending to standby */
+       if (suggested_node_id == -1)
+       {
+               /* If the weight is less than random rate then send to primary. */
+               if ((index_db >= 0 && r > pool_config->db_redirect_tokens->token[index_db].weight_token) ||
+                       (index_app >= 0 && r > pool_config->app_name_redirect_tokens->token[index_app].weight_token))
+               {
+                       ereport(DEBUG1,
+                                       (errmsg("selecting load balance node"),
+                                        errdetail("selected backend id is %d", PRIMARY_NODE_ID)));
+                       return PRIMARY_NODE_ID;
+               }
        }
 
        /* Choose a backend in random manner with weight */
@@ -1753,6 +1791,8 @@ int select_load_balancing_node(void)
        {
                if (VALID_BACKEND(i))
                {
+                       if (i == no_load_balance_node_id)
+                               continue;
                        if (suggested_node_id == -1)
                        {
                                if (i != PRIMARY_NODE_ID)
@@ -1772,7 +1812,7 @@ int select_load_balancing_node(void)
        total_weight = 0.0;
        for (i=0;i<NUM_BACKENDS;i++)
        {
-               if (suggested_node_id == -1 && i == PRIMARY_NODE_ID)
+               if ((suggested_node_id == -1 && i == PRIMARY_NODE_ID) || i == no_load_balance_node_id)
                        continue;
 
                if (VALID_BACKEND(i) && BACKEND_INFO(i).backend_weight > 0.0)
index 70e256e4f970bb21cdba97ded187218c0e7fba1c..9c28512cb0a39ee6a11345eaba8069ef48c4819b 100644 (file)
@@ -1 +1 @@
-SELECT 'test6'
+SELECT 'test11'
diff --git a/src/test/regression/tests/008.dbredirect/select1.pgbench b/src/test/regression/tests/008.dbredirect/select1.pgbench
new file mode 100644 (file)
index 0000000..951c803
--- /dev/null
@@ -0,0 +1 @@
+SELECT 'test9'
index 64bfafbf54c149c5f696dcd42a22e1a50e8eae78..0437773552f169cef5a5e8e6226ecb3141ac6985 100755 (executable)
@@ -25,7 +25,7 @@ echo "done."
 
 source ./bashrc.ports
 
-echo "database_redirect_preference_list = 'postgres:primary,test:1,mydb[5-9]:2,test2:standby'" >> etc/pgpool.conf
+echo "database_redirect_preference_list = 'postgres:primary,test:1,mydb[5-9]:2,test2:standby,test3:primary(0.0),test4:standby(0.0),test5:primary(1.0)'" >> etc/pgpool.conf
 
 ./startall
 
@@ -34,6 +34,9 @@ wait_for_pgpool_startup
 
 $CREATEDB mydb6
 $CREATEDB test2
+$CREATEDB test3
+$CREATEDB test4
+$CREATEDB test5
 $PGBENCH -i postgres
 
 ok=yes
@@ -41,22 +44,45 @@ ok=yes
 # should be redirect to primary (node 0)
 $PSQL -c "SELECT 'test1'" postgres
 
-test `getnode "test1"` -eq 0 || ok=ng
+test `getnode "'test1'"` -eq 0 || ok=ng
+echo $ok
 
 # should be redirect to node 1
 $PSQL -c "SELECT 'test2'" test
 
-test `getnode "test2"` -eq 1 || ok=ng
+test `getnode "'test2'"` -eq 1 || ok=ng
+echo $ok
 
 # should be redirect to node 2
 $PSQL -c "SELECT 'test3'" mydb6
 
-test `getnode "test3"` -eq 2 || ok=ng
+test `getnode "'test3'"` -eq 2 || ok=ng
 
+echo $ok
 # should be redirect to either node 1 or 2
 $PSQL -c "SELECT 'test4'" test2
 
-test `getnode "test4"` -eq 1 -o `getnode "test4"` -eq 2 || ok=ng
+test `getnode "'test4'"` -eq 1 -o `getnode "test4"` -eq 2 || ok=ng
+echo $ok
+
+# should be redirect to either node 1 or 2
+$PSQL -c "SELECT 'test5'" test3
+
+test `getnode "'test5'"` -eq 1 -o `getnode "test5"` -eq 2 || ok=ng
+echo $ok
+
+# should be redirect to primary (node 0)
+$PSQL -c "SELECT 'test6'" test4
+
+test `getnode "'test6'"` -eq 0 || ok=ng
+echo $ok
+
+# should be redirect to primary (node 0)
+$PSQL -c "SELECT 'test7'" test5
+
+test `getnode "'test7'"` -eq 0 || ok=ng
+
+echo $ok
 
 echo "app_name_redirect_preference_list = 'psql:primary,pgbench:standby'" >> etc/pgpool.conf
 
@@ -66,14 +92,36 @@ sleep 1
 wait_for_pgpool_startup
 
 # should be redirect to node 0 because application name is psql
-$PSQL -c "SELECT 'test5'" mydb6
+$PSQL -c "SELECT 'test8'" mydb6
 
-test `getnode "test5"` -eq 0 || ok=ng
+test `getnode "'test8'"` -eq 0 || ok=ng
 
+echo $ok
 # should be redirect to either node 1 or 2
 $PGBENCH -t 1 -f ../select.pgbench postgres
 
-test `getnode "test6"` -eq 1 -o `getnode "test6"` -eq 2 || ok=ng
+test `getnode "'test9'"` -eq 1 -o `getnode "test9"` -eq 2 || ok=ng
+echo $ok
+
+
+echo "app_name_redirect_preference_list = 'psql:primary(0.0),pgbench:standby(1.0)'" >> etc/pgpool.conf
+
+./pgpool_reload
+sleep 1
+
+wait_for_pgpool_startup
+
+# should be redirect to either node 1 or 2
+$PSQL -c "SELECT 'test10'" mydb6
+
+test `getnode "'test10'"` -eq 1 -o `getnode "test10"` -eq 2 || ok=ng
+echo $ok
+
+# should be redirect to either node 1 or 2
+$PGBENCH -t 1 -f ../select1.pgbench postgres
+
+test `getnode "'test11'"` -eq 1 -o `getnode "test11"` -eq 2 || ok=ng
+echo $ok
 
 ./shutdownall
 
index 5541d27fc67077f721a082a5a915f7aa9f25f1a7..f85c16896d02205693ed4b77138a10ab7bf60dcf 100644 (file)
@@ -193,11 +193,13 @@ void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_to
                int len;
                char *left_token;
                char *right_token;
+               char *weight_token = NULL;
                int i,j;
 
                len = strlen(token)+1;
                left_token = palloc(len);
                right_token = palloc(len);
+               weight_token = palloc(len);
 
                for (i=0;token[i] && token[i] != delimi2;i++)
                        left_token[i] = token[i];
@@ -216,11 +218,21 @@ void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_to
                i++;
                j = 0;
 
-               for (;token[i];i++)
+               for (;token[i] && token[i] != '('; i++)
                        right_token[j++] = token[i];
 
                right_token[j] = '\0';
 
+               /* delimiter 3 */
+               int k = 0;
+               if (token[i] == '(')
+               {
+                       i++;
+                       for (;token[i] && token[i] != ')'; i++)
+                               weight_token[k++] = token[i];
+               }
+               weight_token[k] = '\0';
+
                if (lrtokens->pos == lrtokens->size)
                {
                        lrtokens->size += AR_ALLOC_UNIT;
@@ -228,6 +240,11 @@ void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_to
                }
                lrtokens->token[lrtokens->pos].left_token = left_token;
                lrtokens->token[lrtokens->pos].right_token = right_token;
+               if (weight_token[0] != '\0')
+                       lrtokens->token[lrtokens->pos].weight_token = atof(weight_token);
+               else
+                       lrtokens->token[lrtokens->pos].weight_token = 1.0;
+
                lrtokens->pos++;
        }
        pfree(mystr);