[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-18 Thread Wietse Venema via Postfix-users
Gerald Galster via Postfix-users:
> 
> > Wietse Venema via Postfix-users :
> > 
> > And here is a more conservative patch for MySQL client retries.
> > 
> > It closes the server connection after every error, and it delays
> > making a new server connection only after specific errors.
> > 
> > Closing the connection eliminates the possibility that the client
> > becomes stuck.
> 
> dict_mysql.c: In function 'plmysql_connect_single':
> dict_mysql.c:709:13: error: too few arguments to function 'plmysql_down_host'
>   709 | plmysql_down_host(host);
> 
> 
> After adding RETRY_CONN_INTV to plmysql_down_host it works.
> My version of 20230417-mysql-charset-patch.txt contained 
> plmysql_down_host(host).
> 
> 
> Setting charset = testcharset yields:
> 
> postfix/proxymap[14072]: warning: dict_mysql: mysql_set_character_set 
> 'testcharset' failed: Can't initialize character set testcharset (path: 
> compiled_in)
> postfix/postmap[14078]: fatal: table 
> proxy:mysql:/etc/postfix/relay_domains.mysql.cf: query error: Application 
> error
> 
> Mysql connects then pause for about a minute.
> 
> Introducing a simple sql syntax error yields:
> 
> postfix/proxymap[15610]: warning: mysql:/etc/postfix/relay_domains.mysql.cf: 
> query failed: You have an error in your SQL syntax...
> 
> There is no pause, every new request hits MySQL.

Well, almost. I spent some time this morning analyzing code, because
I was suspicious that this 'no delay after error' fix did not cause
the code to go into a fast retry loop.

The reason it does not loop is that there will be a delay of up to
one second, because the delay is in effect while some deadline >=
current_time (the time is measured with one-second resolution).

While the delay is in effect, I discovered that the MySQL client
will reply with "not found" instead of "error". That bug was
introduced in Postfix 3.2, a 'missing initialization' error that
none of my compilers reported.

I can't eliminate the up-to-one-second delay (changing the code
to delay while 'deadline > current_time'), because the MySQL client
would go into a fast retry loop. Fixing that would require more
invasive changes than I can reasonably do in a stable release.

Consdering that

- the 60-second delay after error has been in effect since the MySQL
client was adopted into Postfix on 19991208,

- the same 60-second delay afer error exists in the PostgreSQL
client,

- there have been no other complaints about the 60-second delay,

I'll not change the stable Postfix releases except for the "not
found instead of error" bug that I mentioned above.

Again, thanks for the assistance with testing. I ended up setting
up a MySQL test locally. I should have done that 24 years ago.

Wietse
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-18 Thread Gerald Galster via Postfix-users


> Wietse Venema via Postfix-users :
> 
> And here is a more conservative patch for MySQL client retries.
> 
> It closes the server connection after every error, and it delays
> making a new server connection only after specific errors.
> 
> Closing the connection eliminates the possibility that the client
> becomes stuck.

dict_mysql.c: In function 'plmysql_connect_single':
dict_mysql.c:709:13: error: too few arguments to function 'plmysql_down_host'
  709 | plmysql_down_host(host);


After adding RETRY_CONN_INTV to plmysql_down_host it works.
My version of 20230417-mysql-charset-patch.txt contained 
plmysql_down_host(host).


Setting charset = testcharset yields:

postfix/proxymap[14072]: warning: dict_mysql: mysql_set_character_set 
'testcharset' failed: Can't initialize character set testcharset (path: 
compiled_in)
postfix/postmap[14078]: fatal: table 
proxy:mysql:/etc/postfix/relay_domains.mysql.cf: query error: Application error

Mysql connects then pause for about a minute.


Introducing a simple sql syntax error yields:

postfix/proxymap[15610]: warning: mysql:/etc/postfix/relay_domains.mysql.cf: 
query failed: You have an error in your SQL syntax...

There is no pause, every new request hits MySQL.


Best regards,
Gerald

___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Wietse Venema via Postfix-users
And here is a more conservative patch for MySQL client retries.

It closes the server connection after every error, and it delays
making a new server connection only after specific errors.

Closing the connection eliminates the possibility that the client
becomes stuck.

Wietse
20230417

Cleanup: in the MySQL client, temporarily stay away from a
server only if the last error was caused by a connection-level
or protocol-level failure. File: global/dict_mysql.c.

diff -ur /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c 
./src/global/dict_mysql.c
--- /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c   2023-04-16 
16:44:39.0 -0400
+++ ./src/global/dict_mysql.c   2023-04-17 19:17:02.0 -0400
@@ -108,6 +108,7 @@
 /* Application-specific. */
 
 #include "dict_mysql.h"
+#include "mysql/errmsg.h"
 
 /* MySQL 8.x API change */
 
@@ -179,7 +180,7 @@
 static int plmysql_query(DICT_MYSQL *, const char *, VSTRING *, MYSQL_RES **);
 static void plmysql_dealloc(PLMYSQL *);
 static void plmysql_close_host(HOST *);
-static void plmysql_down_host(HOST *);
+static void plmysql_down_host(HOST *, int);
 static void plmysql_connect_single(DICT_MYSQL *, HOST *);
 static const char *dict_mysql_lookup(DICT *, const char *);
 DICT   *dict_mysql_open(const char *, int, int);
@@ -546,7 +547,16 @@
 * See what we got.
 */
if (query_error) {
-   plmysql_down_host(host);
+   switch (mysql_errno(host->db)) {
+   case CR_COMMANDS_OUT_OF_SYNC:
+   case CR_SERVER_GONE_ERROR:
+   case CR_SERVER_LOST:
+   plmysql_down_host(host, RETRY_CONN_INTV);
+   break;
+   default:
+   plmysql_down_host(host, 0);
+   break;
+   }
if (errno == 0)
errno = ENOTSUP;
if (first_result) {
@@ -609,7 +619,7 @@
 } else {
msg_warn("connect to mysql server %s: %s",
 host->hostname, mysql_error(host->db));
-   plmysql_down_host(host);
+   plmysql_down_host(host, RETRY_CONN_INTV);
 }
 }
 
@@ -625,11 +635,11 @@
  * plmysql_down_host - close a failed connection AND set a "stay away from
  * this host" timer
  */
-static void plmysql_down_host(HOST *host)
+static void plmysql_down_host(HOST *host, int delay)
 {
 mysql_close(host->db);
 host->db = 0;
-host->ts = time((time_t *) 0) + RETRY_CONN_INTV;
+host->ts = time((time_t *) 0) + delay;
 host->stat = STATFAIL;
 event_cancel_timer(dict_mysql_event, (void *) host);
 }
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Gerald Galster via Postfix-users
>>> I've patched postfix 3.7.4 on a low volume server.
>> 
>> Thank you!
>> 
>>> "charset" has to be present and defined in all mysql configs, otherwise 
>>> startup fails:
>>> (no backwards compatibility)
>>> 
>>> postfix/proxymap[3996]: fatal: /etc/postfix/test.mysql.cf: bad string 
>>> length 0 < 1: charset =
>> 
>> Grr. In the patch, 
>> 
>>cfg_get_int(stuff, "charset", "", 1, 0) 
>> 
>> should be
>> 
>>cfg_get_int(stuff, "charset", "", 0, 0)
> 
> That should be cfg_get_str.

Thanks, I modified dict_mysql.c, recompiled and now it works as expected.

Best regards,
Gerald___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Wietse Venema via Postfix-users
Wietse Venema via Postfix-users:
> Gerald Galster via Postfix-users:
> > 
> > > Wietse Venema via Postfix-users :
> > > 
> > >>> My conclusion to hard-solve this issue on my system is transform all 
> > >>> tables to utf8mb4.
> > >>> 
> > >>> But:
> > > 
> > >>> - I don't see any option to change default charset on mysql_table 
> > >>> connector, maybe should be interesting add this option on configuration 
> > >>> file.
> > >> 
> > >> Is there such an API?
> > > 
> > > Based on documentation, perhaps mysql_set_character_set() can do that. 
> > > https://dev.mysql.com/doc/c-api/8.0/en/mysql-set-character-set.html
> > > 
> > > Attached is patch 20230417-mysql-charset-patch.txt that adds a
> > > "charset" parameter to the Postfix MySQL configuration file.
> > 
> > 
> > I've patched postfix 3.7.4 on a low volume server.
> 
> Thank you!
> 
> > "charset" has to be present and defined in all mysql configs, otherwise 
> > startup fails:
> > (no backwards compatibility)
> > 
> > postfix/proxymap[3996]: fatal: /etc/postfix/test.mysql.cf: bad string 
> > length 0 < 1: charset =
> 
> Grr. In the patch, 
> 
> cfg_get_int(stuff, "charset", "", 1, 0) 
> 
> should be
> 
> cfg_get_int(stuff, "charset", "", 0, 0)

That should be cfg_get_str.

Wietse

> > Setting "charset" to the non-default cp1250 works (from mysql general_log):
> > 
> > (terminal encoding utf8)
> > # postmap -q "bl?.com" mysql:/etc/postfix/relay_domains.mysql.cf  
> > Connect postfix@localhost on postfix using Socket
> > Query SET NAMES cp1250
> > Query SELECT destination as relaydestination FROM relay WHERE domain = 
> > 'bl?.com'
> > Quit 
> > (postfix restart)
> > 
> > (terminal encoding latin1)
> > # postmap -q "bl?.com" mysql:/etc/postfix/relay_domains.mysql.cf
> > Connect postfix@localhost on postfix using Socket
> > Query SET NAMES cp1250
> > Query SELECT destination as relaydestination FROM relay WHERE domain = 
> > 'bl?.com'
> > 
> > Unfortunately I can't help with mix collation error as this mysql 8 instance
> > is configured with utf8mb4/utf8_bin, skip-character-set-client-handshake and
> > all tables are utf8mb4. I could not trigger a collation error.
> 
> No problem, I am happy that the patch does not break something that
> works without the patch.
> 
> > +# .IP "\fBcharset\fR (empty for backwards compatibility)"
> > +# The default client character set (and implicitly, the
> > +# collation order). According to MySQL documentation the
> > +# built-in default is "latin1"; for SMTP, "utf8" would be
> > +# more appropriate.
> > 
> > As of mysql 8.0 the default character set is utf8mb4:
> > https://dev.mysql.com/blog-archive/mysql-8-0-collations-migrating-from-older-collations/
> 
> I'll delete the comnment about "latin1" as it is MySQL version dependent.
> 
> > Historically utf8 had been a mysql alias for utf8mb3:
> > https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html
> 
> Again, thanks for what you could test. The error handling should
> be better because the new code will no longer skip a connection
> for 60s after every errror, but only after an error that involves a
> really messed-up connection.
> 
>   Wietse
> ___
> Postfix-users mailing list -- postfix-users@postfix.org
> To unsubscribe send an email to postfix-users-le...@postfix.org
> 
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Wietse Venema via Postfix-users
Gerald Galster via Postfix-users:
> 
> > Wietse Venema via Postfix-users :
> > 
> >>> My conclusion to hard-solve this issue on my system is transform all 
> >>> tables to utf8mb4.
> >>> 
> >>> But:
> > 
> >>> - I don't see any option to change default charset on mysql_table 
> >>> connector, maybe should be interesting add this option on configuration 
> >>> file.
> >> 
> >> Is there such an API?
> > 
> > Based on documentation, perhaps mysql_set_character_set() can do that. 
> > https://dev.mysql.com/doc/c-api/8.0/en/mysql-set-character-set.html
> > 
> > Attached is patch 20230417-mysql-charset-patch.txt that adds a
> > "charset" parameter to the Postfix MySQL configuration file.
> 
> 
> I've patched postfix 3.7.4 on a low volume server.

Thank you!

> "charset" has to be present and defined in all mysql configs, otherwise 
> startup fails:
> (no backwards compatibility)
> 
> postfix/proxymap[3996]: fatal: /etc/postfix/test.mysql.cf: bad string length 
> 0 < 1: charset =

Grr. In the patch, 

cfg_get_int(stuff, "charset", "", 1, 0) 

should be

cfg_get_int(stuff, "charset", "", 0, 0)

> Setting "charset" to the non-default cp1250 works (from mysql general_log):
> 
> (terminal encoding utf8)
> # postmap -q "bl?.com" mysql:/etc/postfix/relay_domains.mysql.cf  
> Connect postfix@localhost on postfix using Socket
> Query SET NAMES cp1250
> Query SELECT destination as relaydestination FROM relay WHERE domain = 
> 'bl?.com'
> Quit 
> (postfix restart)
> 
> (terminal encoding latin1)
> # postmap -q "bl?.com" mysql:/etc/postfix/relay_domains.mysql.cf
> Connect postfix@localhost on postfix using Socket
> Query SET NAMES cp1250
> Query SELECT destination as relaydestination FROM relay WHERE domain = 
> 'bl?.com'
> 
> Unfortunately I can't help with mix collation error as this mysql 8 instance
> is configured with utf8mb4/utf8_bin, skip-character-set-client-handshake and
> all tables are utf8mb4. I could not trigger a collation error.

No problem, I am happy that the patch does not break something that
works without the patch.

> +# .IP "\fBcharset\fR (empty for backwards compatibility)"
> +# The default client character set (and implicitly, the
> +# collation order). According to MySQL documentation the
> +# built-in default is "latin1"; for SMTP, "utf8" would be
> +# more appropriate.
> 
> As of mysql 8.0 the default character set is utf8mb4:
> https://dev.mysql.com/blog-archive/mysql-8-0-collations-migrating-from-older-collations/

I'll delete the comnment about "latin1" as it is MySQL version dependent.

> Historically utf8 had been a mysql alias for utf8mb3:
> https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html

Again, thanks for what you could test. The error handling should
be better because the new code will no longer skip a connection
for 60s after every errror, but only after an error that involves a
really messed-up connection.

Wietse
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Gerald Galster via Postfix-users

> Wietse Venema via Postfix-users :
> 
>>> My conclusion to hard-solve this issue on my system is transform all 
>>> tables to utf8mb4.
>>> 
>>> But:
> 
>>> - I don't see any option to change default charset on mysql_table 
>>> connector, maybe should be interesting add this option on configuration 
>>> file.
>> 
>> Is there such an API?
> 
> Based on documentation, perhaps mysql_set_character_set() can do that. 
> https://dev.mysql.com/doc/c-api/8.0/en/mysql-set-character-set.html
> 
> Attached is patch 20230417-mysql-charset-patch.txt that adds a
> "charset" parameter to the Postfix MySQL configuration file.


I've patched postfix 3.7.4 on a low volume server.

"charset" has to be present and defined in all mysql configs, otherwise startup 
fails:
(no backwards compatibility)

postfix/proxymap[3996]: fatal: /etc/postfix/test.mysql.cf: bad string length 0 
< 1: charset =
postfix/smtpd[3995]: warning: dict_proxy_open: service proxymap: Application 
error
postfix/master[3989]: warning: process /usr/libexec/postfix/proxymap pid 3996 
exit status 1
postfix/master[3989]: warning: /usr/libexec/postfix/proxymap: bad command 
startup -- throttling

Setting "charset" to the non-default cp1250 works (from mysql general_log):

(terminal encoding utf8)
# postmap -q "blü.com" mysql:/etc/postfix/relay_domains.mysql.cf  
Connect postfix@localhost on postfix using Socket
Query SET NAMES cp1250
Query SELECT destination as relaydestination FROM relay WHERE domain = 'blü.com'
Quit 
(postfix restart)

(terminal encoding latin1)
# postmap -q "bl?.com" mysql:/etc/postfix/relay_domains.mysql.cf
Connect postfix@localhost on postfix using Socket
Query SET NAMES cp1250
Query SELECT destination as relaydestination FROM relay WHERE domain = 'blü.com'

Unfortunately I can't help with mix collation error as this mysql 8 instance
is configured with utf8mb4/utf8_bin, skip-character-set-client-handshake and
all tables are utf8mb4. I could not trigger a collation error.
 

+++ ./proto/mysql_table 2023-04-17 11:24:16.0 -0400
@@ -79,6 +79,11 @@
 # .nf
 #dbname = customer_database
 # .fi
+# .IP "\fBcharset\fR (empty for backwards compatibility)"
+# The default client character set (and implicitly, the
+# collation order). According to MySQL documentation the
+# built-in default is "latin1"; for SMTP, "utf8" would be
+# more appropriate.

As of mysql 8.0 the default character set is utf8mb4:
https://dev.mysql.com/blog-archive/mysql-8-0-collations-migrating-from-older-collations/

Historically utf8 had been a mysql alias for utf8mb3:
https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html

Best regards,
Gerald

___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Wietse Venema via Postfix-users
Wietse Venema via Postfix-users:
> > My conclusion to hard-solve this issue on my system is transform all 
> > tables to utf8mb4.
> > 
> > But:

> > - I don't see any option to change default charset on mysql_table 
> > connector, maybe should be interesting add this option on configuration 
> > file.
> 
> Is there such an API?

Based on documentation, perhaps mysql_set_character_set() can do that. 
https://dev.mysql.com/doc/c-api/8.0/en/mysql-set-character-set.html

Attached is patch 20230417-mysql-charset-patch.txt that adds a
"charset" parameter to the Postfix MySQL configuration file.  

I don't have a MySQL testbed; someone else would have to test this,
or this would have to wait until I have time to set up MySQL.

> > - mix collation error should raise 1 error, but next queries should be 
> > work ok, this could be considered and issue right?.
> 
> For the Postfix MySQL client the expected result of a query is:
> 
> - found,
> 
> - not found,
> 
> - error.
> 
> The client does not distinguish between errors, and all errors have
> the same result (skip this connection for 60s). That code is almost
> 20 years old, so I wonder if you are doing something unusal that
> other people aren't doing.
> 
> Based on https://dev.mysql.com/doc/c-api/8.0/en/mysql-next-result.html
> I suppose that the client could distinguish between
> errors that indicate a connection error and other errors. But that
> would be a major code change.

It is possible to distinguish between errors without having tp
restructure code.

Attached is patch 20230417-mysql-retry-patch.txt that more selectively
backs off from a server connection. 

Again if someone else can test this, great, otherwise this will
have to wait.

Wietse
20230417

Cleanup: in the MySQL client, temporarily stay away from a
server only if the last error was caused by connection-level
failure. File: global/dict_mysql.c.

diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' 
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur 
/var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c ./src/global/dict_mysql.c
--- /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c   2023-04-16 
16:44:39.0 -0400
+++ ./src/global/dict_mysql.c   2023-04-17 11:07:47.0 -0400
@@ -108,6 +108,7 @@
 /* Application-specific. */
 
 #include "dict_mysql.h"
+#include "mysql/errmsg.h"
 
 /* MySQL 8.x API change */
 
@@ -546,7 +547,14 @@
 * See what we got.
 */
if (query_error) {
-   plmysql_down_host(host);
+   switch (mysql_errno(host->db)) {
+   case CR_COMMANDS_OUT_OF_SYNC:
+   case CR_SERVER_GONE_ERROR:
+   case CR_SERVER_LOST:
+   plmysql_down_host(host);
+   default:
+   break;
+   }
if (errno == 0)
errno = ENOTSUP;
if (first_result) {
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' 
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur 
/var/tmp/postfix-3.9-20230416/HISTORY ./HISTORY
--- /var/tmp/postfix-3.9-20230416/HISTORY   2023-04-16 17:09:29.0 
-0400
+++ ./HISTORY   2023-04-17 11:01:00.531589777 -0400
@@ -27055,3 +27055,9 @@
Cleanup: in source-code comments, replaced redundant (and
sometimes incomplete) lookup table configuration info with
a reference to the corresponding *_table(5) manpage.
+
+20230417
+
+   Cleanup: in the MySQL client, make the default characterset
+   (and collation) configurable (the MySQL defaults are latin1
+   and latin1_swedish_ci). File: global/dict_mysql.c.
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' 
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur 
/var/tmp/postfix-3.9-20230416/proto/mysql_table ./proto/mysql_table
--- /var/tmp/postfix-3.9-20230416/proto/mysql_table 2022-12-27 
18:01:00.0 -0500
+++ ./proto/mysql_table 2023-04-17 11:24:16.0 -0400
@@ -79,6 +79,11 @@
 # .nf
 #  dbname = customer_database
 # .fi
+# .IP "\fBcharset\fR (empty for backwards compatibility)"
+#  The default client character set (and implicitly, the
+#  collation order). According to MySQL documentation the
+#  built-in default is "latin1"; for SMTP, "utf8" would be
+#  more appropriate.
 # .IP "\fBquery\fR"
 #  The SQL query template used to search the database, where \fB%s\fR
 #  is a substitute for the address Postfix is trying to resolve,
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' 
'--exclude=INSTALL' '--exclude=.indent.pro' -r -ur 
/var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c ./src/global/dict_mysql.c
--- /var/tmp/postfix-3.9-20230416/src/global/dict_mysql.c   2023-04-16 
16:44:39.0 -0400
+++ ./src/global/dict_mysql.c   2023-04-17 11:09:35.0 -0400
@@ -147,6 +147,7 @@
 char   *username;
 char   *password;
 char   *dbname;
+char   *charset;
 ARGV   *hosts;
 PLMYSQL *pldb;
 #if 

[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-17 Thread Wietse Venema via Postfix-users
V?ctor Rubiella Monfort via Postfix-users:
> Hi, I have more info and I try to explain it better:
> 
> First of all I have smtputf8_enable = no (disabled).
> 
> I have several databases related with several mysql_virtual maps:
> 
> - Some with utf8 + utf8_general_ci collation
> 
> - Another ones with latin1 + latin1_spanish_ci.
> 
> I'm using mysql-postfix (mysql_table) lookups, not postgres. 
> "proxy:mysql:/XXX.cf".
> 
> I can reproduce same issue with both cf files (tables with utf8 and 
> tables with latin1).
> 
> As I say before, the worst part is when error is raised during about 1 
> minute all lookups raises failures.
> 
> Error is easy to reproduce manually calling to "postmap -q 
> "emailWithspecialchar" "proxy:mysql:/XXX.cf"
> 
> Debugging I observe 2 things.
> 
> - adding CONVERT('%s' using ascii) fix the issue but I don't want/like 
> add converts on all my sql queries...
> 
> - adding COLLATE utf8_general_ci raises error "this collate is not valid 
> for utf8mb4". This error shows me than mysql_table lookup connections 
> are using "utf8mb4" charset by default.
> 
> My conclusion to hard-solve this issue on my system is transform all 
> tables to utf8mb4.
> 
> But:
> 
> - I don't see any option to change default charset on mysql_table 
> connector, maybe should be interesting add this option on configuration 
> file.

Is there such an API?

> - mix collation error should raise 1 error, but next queries should be 
> work ok, this could be considered and issue right?.

For the Postfix MySQL client the expected result of a query is:

- found,

- not found,

- error.

The client does not distinguish between errors, and all errors have
the same result (skip this connection for 60s). That code is almost
20 years old, so I wonder if you are doing something unusal that
other people aren't doing.

Based on https://dev.mysql.com/doc/c-api/8.0/en/mysql-next-result.html
I suppose that the client could distinguish between
errors that indicate a connection error and other errors. But that
would be a major code change.

It would help if you could show the warning that Postfix logs.

mysql:/file/name: query failed (mysql_next_result): >>>THIS TEXT

> - with "smtputf8_enable = no" I should be able to work without this kind 
> of issues right?

No. With "smtputf8_enable = no", Postfix will not verify that a
query contains malformed text. This can result in errors from the
MySQL server.

On the other hand, with "smtputf8_enable = yes", Postfix will skip
a query that contains malformed UTF-8, thus avoiding errors from
the MySQL server.

> For modern protocols I can undestant change to utf8, but utf8mb4? this 
> is much more expensive for the database, is it really necessary?

By design UTF-8 is a multi-byte encoding for all non-ASCII characters.
The only single-byte in UTF-8 is the ASCII subset.

Wietse
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Wietse Venema via Postfix-users
Viktor Dukhovni via Postfix-users:
> On Fri, Apr 14, 2023 at 01:06:16PM -0400, Wietse Venema via Postfix-users 
> wrote:
> 
> > Wietse Venema via Postfix-users:
> > > As for the temp error becoming persistent, the Postfix pgsql: client
> > > code returns an error when it gets an error from all of the hosts
> > > configured in the Postfix pgsql: client configuration file, or when
> > > all hosts have been flagged as 'down'. If a host returns an error
> > > then the Postfix pgsql: client code flags that host as 'down', and
> > > resets that 'down' state after about 60 seconds.
> > 
> > As implemented, the Postfix pgsql: clien code treats all errors as
> > a connection failure, and skips the connection for 60 seconds. That
> > may not be optimal when an error is data dependent.
> 
> FWIW, the OP's issue was with MySQL, not Postgres...  The database
> should be configured for client and server encoding of UTF8.

Oops. Where did I get that from. There is no hard-coded encoding type
in the Postfix mysql client. With smtputf8_enable=yes, Postfix will
accept email addresses with well-formed UTF8 (and ASCII) but not Latin1.

Wietse
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Víctor Rubiella Monfort via Postfix-users

Hi, I have more info and I try to explain it better:

First of all I have smtp_utf8 = no (disabled).

I have several databases related with several mysql_virtual maps:

- Some with utf8 + utf8_general_ci collation

- Another ones with latin1 + latin1_spanish_ci.

I'm using mysql-postfix (mysql_table) lookups, not postgres. 
"proxy:mysql:/XXX.cf".


I can reproduce same issue with both cf files (tables with utf8 and 
tables with latin1).


As I say before, the worst part is when error is raised during about 1 
minute all lookups raises failures.


Error is easy to reproduce manually calling to "postmap -q 
"emailWithspecialchar" "proxy:mysql:/XXX.cf"


Debugging I observe 2 things.

- adding CONVERT('%s' using ascii) fix the issue but I don't want/like 
add converts on all my sql queries...


- adding COLLATE utf8_general_ci raises error "this collate is not valid 
for utf8mb4". This error shows me than mysql_table lookup connections 
are using "utf8mb4" charset by default.


My conclusion to hard-solve this issue on my system is transform all 
tables to utf8mb4.


But:

- I don't see any option to change default charset on mysql_table 
connector, maybe should be interesting add this option on configuration 
file.


- mix collation error should raise 1 error, but next queries should be 
work ok, this could be considered and issue right?.


- with "smtputf8_enable = no" I should be able to work without this kind 
of issues right?


For modern protocols I can undestant change to utf8, but utf8mb4? this 
is much more expensive for the database, is it really necessary?


**


El 14/4/23 a las 20:46, Viktor Dukhovni via Postfix-users escribió:

On Fri, Apr 14, 2023 at 01:06:16PM -0400, Wietse Venema via Postfix-users wrote:


Wietse Venema via Postfix-users:

As for the temp error becoming persistent, the Postfix pgsql: client
code returns an error when it gets an error from all of the hosts
configured in the Postfix pgsql: client configuration file, or when
all hosts have been flagged as 'down'. If a host returns an error
then the Postfix pgsql: client code flags that host as 'down', and
resets that 'down' state after about 60 seconds.

As implemented, the Postfix pgsql: clien code treats all errors as
a connection failure, and skips the connection for 60 seconds. That
may not be optimal when an error is data dependent.

FWIW, the OP's issue was with MySQL, not Postgres...  The database
should be configured for client and server encoding of UTF8.
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Viktor Dukhovni via Postfix-users
On Fri, Apr 14, 2023 at 01:06:16PM -0400, Wietse Venema via Postfix-users wrote:

> Wietse Venema via Postfix-users:
> > As for the temp error becoming persistent, the Postfix pgsql: client
> > code returns an error when it gets an error from all of the hosts
> > configured in the Postfix pgsql: client configuration file, or when
> > all hosts have been flagged as 'down'. If a host returns an error
> > then the Postfix pgsql: client code flags that host as 'down', and
> > resets that 'down' state after about 60 seconds.
> 
> As implemented, the Postfix pgsql: clien code treats all errors as
> a connection failure, and skips the connection for 60 seconds. That
> may not be optimal when an error is data dependent.

FWIW, the OP's issue was with MySQL, not Postgres...  The database
should be configured for client and server encoding of UTF8.

-- 
Viktor.
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Wietse Venema via Postfix-users
Wietse Venema via Postfix-users:
> As for the temp error becoming persistent, the Postfix pgsql: client
> code returns an error when it gets an error from all of the hosts
> configured in the Postfix pgsql: client configuration file, or when
> all hosts have been flagged as 'down'. If a host returns an error
> then the Postfix pgsql: client code flags that host as 'down', and
> resets that 'down' state after about 60 seconds.

As implemented, the Postfix pgsql: clien code treats all errors as
a connection failure, and skips the connection for 60 seconds. That
may not be optimal when an error is data dependent.

What error did Postfix log for a bad query? It would be helpful if
you could look in your logs for the exact error message.

The relevant code is below my signature.

Wietse

if ((res = PQexec(host->db, vstring_str(query))) != 0) {
...
switch ((status = PQresultStatus(res))) {
case PGRES_TUPLES_OK:
case PGRES_COMMAND_OK:
/* Success. */
if (msg_verbose)
msg_info("dict_pgsql: successful query from host %s",
 host->hostname);
event_request_timer(dict_pgsql_event, (void *) host,
dict_pgsql->idle_interval);
return (res);
case PGRES_FATAL_ERROR:
msg_warn("pgsql query failed: fatal error from host %s: %s",
 host->hostname, PQresultErrorMessage(res));
break;
case PGRES_BAD_RESPONSE:
msg_warn("pgsql query failed: protocol error, host %s",
 host->hostname);
break;
default:
msg_warn("pgsql query failed: unknown code 0x%lx from host %s",
 (unsigned long) status, host->hostname);
break;
}
} else {
...
msg_warn("pgsql query failed: fatal error from host %s: %s",
 host->hostname, PQerrorMessage(host->db));
}
...
/*
 * XXX An error occurred. Clean up memory and skip this connection.
 */
...
plpgsql_down_host(dict_pgsql, host);

___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Wietse Venema via Postfix-users
V?ctor Rubiella Monfort via Postfix-users:
> Hi again,
> 
> I realized than same error is raised when database is in utf8 if email 
> contains utf8mb4 characters.
> 
> Which is the convenient database collation for postfix? We can force 
> postfix to accept only utf8 characters?.

With "smtputf8_enable = yes" in main.cf, Postfix will accept
well-formed UTF-8. However, before Postfix 3.8, the Postfix pgsql:
client code sets the client encoding to LATIN1.

The client encoding is configurable (default: UTF8) with Postfix
3.8 which is to be released soon (postfix-3.8.0-RC1 was published
a few days ago).

As for the temp error becoming persistent, the Postfix pgsql: client
code returns an error when it gets an error from all of the hosts
configured in the Postfix pgsql: client configuration file, or when
all hosts have been flagged as 'down'. If a host returns an error
then the Postfix pgsql: client code flags that host as 'down', and
resets that 'down' state after about 60 seconds.

In your case having multiple hosts configured in the Postfix pgsql:
client configuration would not help, because they would have the
same error.

Wietse
> 
> 
> El 13/4/23 a las 18:36, V?ctor Rubiella Monfort via Postfix-users escribi?:
> > When mysql_table lookup is executing nonascii characters and database 
> > is in latin1, not only fails query, all sesion/connection is corrupted 
> > and produces a lot of "temporary lookup table" errors until sesion is 
> > recreated (about 1 minute later).
> >
> > Today some external ip was trying to deliver an email with special 
> > character on one on my legacy servers (with latin1) and produces this 
> > errors.
> >
> > I can understant that lookup fails for query with special characters, 
> > but main issue was for all raised failures for other accounts and 
> > lookups during 1-2 minutes. This is a knew issue?.
> >
> >
> > I deploy an workaround using "CONVERT('%s' using ascii)" until not 
> > pass all database tables to utf8.
> >
> > The main problem debuging this issue was "proxy:mysql" , "proxy" was 
> > hiding original collation error and only shows regular lookup errors 
> > on postfix log, when user "postmap" to debug, I only see root cause 
> > when execute without "proxy".
> >
> > postfix versions tested:
> >
> > postfix 3.5.17-0+deb11u1
> > postfix-mysql??? 3.5.17-0+deb11u1
> >
> > postfix 3.5.15-0+deb11u1
> > postfix-mysql??? 3.5.15-0+deb11u1
> >
> >
> >
> >
> > ___
> > Postfix-users mailing list -- postfix-users@postfix.org
> > To unsubscribe send an email to postfix-users-le...@postfix.org
> ___
> Postfix-users mailing list -- postfix-users@postfix.org
> To unsubscribe send an email to postfix-users-le...@postfix.org
> 
___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org


[pfx] Re: temporary lookup error with utf8mb4 characters

2023-04-14 Thread Víctor Rubiella Monfort via Postfix-users

Hi again,

I realized than same error is raised when database is in utf8 if email 
contains utf8mb4 characters.


Which is the convenient database collation for postfix? We can force 
postfix to accept only utf8 characters?.




El 13/4/23 a las 18:36, Víctor Rubiella Monfort via Postfix-users escribió:
When mysql_table lookup is executing nonascii characters and database 
is in latin1, not only fails query, all sesion/connection is corrupted 
and produces a lot of "temporary lookup table" errors until sesion is 
recreated (about 1 minute later).


Today some external ip was trying to deliver an email with special 
character on one on my legacy servers (with latin1) and produces this 
errors.


I can understant that lookup fails for query with special characters, 
but main issue was for all raised failures for other accounts and 
lookups during 1-2 minutes. This is a knew issue?.



I deploy an workaround using "CONVERT('%s' using ascii)" until not 
pass all database tables to utf8.


The main problem debuging this issue was "proxy:mysql" , "proxy" was 
hiding original collation error and only shows regular lookup errors 
on postfix log, when user "postmap" to debug, I only see root cause 
when execute without "proxy".


postfix versions tested:

postfix 3.5.17-0+deb11u1
postfix-mysql    3.5.17-0+deb11u1

postfix 3.5.15-0+deb11u1
postfix-mysql    3.5.15-0+deb11u1




___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org

___
Postfix-users mailing list -- postfix-users@postfix.org
To unsubscribe send an email to postfix-users-le...@postfix.org