walsender & parallelism
Hi,
Since [1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7c4f52409a8c7d85ed169bbbc1f6092274d03920 walsender (not receiver as commit message says) can execute
SQL queries. While doing some testing of [2]http://archives.postgresql.org/message-id/30242bc6-eca4-b7bb-670e-8d0458753a8c%402ndquadrant.com I noticed that SQL queries
in walsender get stuck if parallelism is used - I have not investigated
why that is yet, but it surely is an issue. On first blush I'd suspect
that some signalling is not wired up correctly (cf. am_walsender branches
in PostgresMain() and such).
This'd be easier to look at if the fairly separate facility of allowing
walsender to execute SQL commands had been committed separately, rather
than as part of a fairly large commit of largely unrelated things.
Greetings,
Andres Freund
[1]: https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7c4f52409a8c7d85ed169bbbc1f6092274d03920
[2]: http://archives.postgresql.org/message-id/30242bc6-eca4-b7bb-670e-8d0458753a8c%402ndquadrant.com
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 21/04/17 03:40, Andres Freund wrote:
Since [1] walsender (not receiver as commit message says) can execute
SQL queries. While doing some testing of [2] I noticed that SQL queries
in walsender get stuck if parallelism is used - I have not investigated
why that is yet, but it surely is an issue. On first blush I'd suspect
that some signalling is not wired up correctly (cf. am_walsender branches
in PostgresMain() and such).
Looks like SIGUSR1 being different is problem here - it's normally used
to . I also noticed that we don't handle SIGINT (query cancel).
I'll write proper patch but can you try to just use
procsignal_sigusr1_handler for SIGUSR1 in walsender.c to see if it fixes
the issue?
BTW while looking at the code, I don't understand why we call
latch_sigusr1_handler after calling SetLatch(MyLatch), shouldn't just
the SetLatch be enough (they both end up calling sendSelfPipeByte()
eventually)?
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 21 April 2017 at 10:20, Petr Jelinek <petr.jelinek@2ndquadrant.com> wrote:
On 21/04/17 03:40, Andres Freund wrote:
Since [1] walsender (not receiver as commit message says) can execute
SQL queries. While doing some testing of [2] I noticed that SQL queries
in walsender get stuck if parallelism is used - I have not investigated
why that is yet, but it surely is an issue. On first blush I'd suspect
that some signalling is not wired up correctly (cf. am_walsender branches
in PostgresMain() and such).Looks like SIGUSR1 being different is problem here - it's normally used
to . I also noticed that we don't handle SIGINT (query cancel).I'll write proper patch but can you try to just use
procsignal_sigusr1_handler for SIGUSR1 in walsender.c to see if it fixes
the issue?
That's what my recovery conflicts for logical decoding on standby
patch does, FWIW.
I haven't found any issues yet..
--
Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 21/04/17 04:32, Craig Ringer wrote:
On 21 April 2017 at 10:20, Petr Jelinek <petr.jelinek@2ndquadrant.com> wrote:
On 21/04/17 03:40, Andres Freund wrote:
Since [1] walsender (not receiver as commit message says) can execute
SQL queries. While doing some testing of [2] I noticed that SQL queries
in walsender get stuck if parallelism is used - I have not investigated
why that is yet, but it surely is an issue. On first blush I'd suspect
that some signalling is not wired up correctly (cf. am_walsender branches
in PostgresMain() and such).Looks like SIGUSR1 being different is problem here - it's normally used
to . I also noticed that we don't handle SIGINT (query cancel).I'll write proper patch but can you try to just use
procsignal_sigusr1_handler for SIGUSR1 in walsender.c to see if it fixes
the issue?That's what my recovery conflicts for logical decoding on standby
patch does, FWIW.I haven't found any issues yet..
Ah I knew I've seen that change somewhere. I thought it was either in my
patch or master which is why I thought it's working fine already.
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 21/04/17 04:37, Petr Jelinek wrote:
On 21/04/17 04:32, Craig Ringer wrote:
On 21 April 2017 at 10:20, Petr Jelinek <petr.jelinek@2ndquadrant.com> wrote:
On 21/04/17 03:40, Andres Freund wrote:
Since [1] walsender (not receiver as commit message says) can execute
SQL queries. While doing some testing of [2] I noticed that SQL queries
in walsender get stuck if parallelism is used - I have not investigated
why that is yet, but it surely is an issue. On first blush I'd suspect
that some signalling is not wired up correctly (cf. am_walsender branches
in PostgresMain() and such).Looks like SIGUSR1 being different is problem here - it's normally used
to . I also noticed that we don't handle SIGINT (query cancel).I'll write proper patch but can you try to just use
procsignal_sigusr1_handler for SIGUSR1 in walsender.c to see if it fixes
the issue?That's what my recovery conflicts for logical decoding on standby
patch does, FWIW.I haven't found any issues yet..
Ah I knew I've seen that change somewhere. I thought it was either in my
patch or master which is why I thought it's working fine already.
Here is patch. I changed both SIGINT and SIGUSR1 handlers, afaics it
does not break anything for existing walsender usage.
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
Handle-signals-correctly-in-walsender.patchtext/plain; charset=UTF-8; name=Handle-signals-correctly-in-walsender.patchDownload
From f59218135092bec9a64cf86b75f1f62a0271d448 Mon Sep 17 00:00:00 2001
From: Petr Jelinek <pjmodos@pjmodos.net>
Date: Fri, 21 Apr 2017 05:11:30 +0200
Subject: [PATCH] Handle signals correctly in walsender
Since we now support SQL queries in walsender, we also need to handle
SIGINT for query cancel and SIGUSR1 for IPC.
---
src/backend/replication/logical/launcher.c | 2 +-
src/backend/replication/walsender.c | 16 ++--------------
2 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index 761fbfa..e9dd886 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -254,7 +254,7 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid,
BackgroundWorker bgw;
BackgroundWorkerHandle *bgw_handle;
int i;
- int slot;
+ int slot = 0;
LogicalRepWorker *worker = NULL;
int nsyncworkers = 0;
TimestampTz now = GetCurrentTimestamp();
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index b4ce75a..78369ae 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -212,7 +212,6 @@ static struct
/* Signal handlers */
static void WalSndSigHupHandler(SIGNAL_ARGS);
-static void WalSndXLogSendHandler(SIGNAL_ARGS);
static void WalSndLastCycleHandler(SIGNAL_ARGS);
/* Prototypes for private functions */
@@ -2830,17 +2829,6 @@ WalSndSigHupHandler(SIGNAL_ARGS)
errno = save_errno;
}
-/* SIGUSR1: set flag to send WAL records */
-static void
-WalSndXLogSendHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- latch_sigusr1_handler();
-
- errno = save_errno;
-}
-
/* SIGUSR2: set flag to do a last cycle and shut down afterwards */
static void
WalSndLastCycleHandler(SIGNAL_ARGS)
@@ -2869,12 +2857,12 @@ WalSndSignals(void)
/* Set up signal handlers */
pqsignal(SIGHUP, WalSndSigHupHandler); /* set flag to read config
* file */
- pqsignal(SIGINT, SIG_IGN); /* not used */
+ pqsignal(SIGINT, StatementCancelHandler); /* query cancel */
pqsignal(SIGTERM, die); /* request shutdown */
pqsignal(SIGQUIT, quickdie); /* hard crash time */
InitializeTimeouts(); /* establishes SIGALRM handler */
pqsignal(SIGPIPE, SIG_IGN);
- pqsignal(SIGUSR1, WalSndXLogSendHandler); /* request WAL sending */
+ pqsignal(SIGUSR1, procsignal_sigusr1_handler);
pqsignal(SIGUSR2, WalSndLastCycleHandler); /* request a last cycle and
* shutdown */
--
2.7.4
On 2017-04-21 04:20:26 +0200, Petr Jelinek wrote:
Looks like SIGUSR1 being different is problem here - it's normally used
to . I also noticed that we don't handle SIGINT (query cancel).
I think we really need to unify the paths between walsender and normal
backends to a much larger degree.
BTW while looking at the code, I don't understand why we call
latch_sigusr1_handler after calling SetLatch(MyLatch), shouldn't just
the SetLatch be enough (they both end up calling sendSelfPipeByte()
eventually)?
Historic raisins - there didn't use to be a SetLatch in
procsignal_sigusr1_handler. That changed when I whacked around catchup &
notify to be based on latches ([1]https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=59f71a0d0b56b2df48db4bf1738aece5551f7a47 and following).
- Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi,
On 2017-04-22 17:53:19 +0200, Petr Jelinek wrote:
Here is patch. I changed both SIGINT and SIGUSR1 handlers, afaics it
does not break anything for existing walsender usage.
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 761fbfa..e9dd886 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -254,7 +254,7 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, BackgroundWorker bgw; BackgroundWorkerHandle *bgw_handle; int i; - int slot; + int slot = 0; LogicalRepWorker *worker = NULL; int nsyncworkers = 0; TimestampTz now = GetCurrentTimestamp();
That seems independent and unnecessary?
-/* SIGUSR1: set flag to send WAL records */
-static void
-WalSndXLogSendHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- latch_sigusr1_handler();
-
- errno = save_errno;
-}
pqsignal(SIGPIPE, SIG_IGN); - pqsignal(SIGUSR1, WalSndXLogSendHandler); /* request WAL sending */ + pqsignal(SIGUSR1, procsignal_sigusr1_handler);
Those aren't actually entirely equivalent. I'm not sure it matters much,
but WalSndXLogSendHandler didn't include a SetLatch(), but
procsignal_sigusr1_handler() does. Normally redundant SetLatch() calls
will just be elided, but what if walsender already woke up and did it's
work?
I think it'd be better to have PostgresMain() set up signals by default,
and then have WalSndSignals() overwrites the ones it needs separate.
WalSndLastCycleHandler is genuinely different. WalSndSigHupHandler
currently sets a different variable from postgres.c, but that seems like
a bad idea, because afaics we'll plainly ignore SIGHUPS unless in
WalSndLoop, WalSndWriteData,WalSndWaitForWal. That actually seems like
an active bug to me?
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi,
On 2017-04-23 16:59:41 -0700, Andres Freund wrote:
Hi,
On 2017-04-22 17:53:19 +0200, Petr Jelinek wrote:
Here is patch. I changed both SIGINT and SIGUSR1 handlers, afaics it
does not break anything for existing walsender usage.diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 761fbfa..e9dd886 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -254,7 +254,7 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, BackgroundWorker bgw; BackgroundWorkerHandle *bgw_handle; int i; - int slot; + int slot = 0; LogicalRepWorker *worker = NULL; int nsyncworkers = 0; TimestampTz now = GetCurrentTimestamp();That seems independent and unnecessary?
-/* SIGUSR1: set flag to send WAL records */
-static void
-WalSndXLogSendHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- latch_sigusr1_handler();
-
- errno = save_errno;
-}pqsignal(SIGPIPE, SIG_IGN); - pqsignal(SIGUSR1, WalSndXLogSendHandler); /* request WAL sending */ + pqsignal(SIGUSR1, procsignal_sigusr1_handler);Those aren't actually entirely equivalent. I'm not sure it matters much,
but WalSndXLogSendHandler didn't include a SetLatch(), but
procsignal_sigusr1_handler() does. Normally redundant SetLatch() calls
will just be elided, but what if walsender already woke up and did it's
work?I think it'd be better to have PostgresMain() set up signals by default,
and then have WalSndSignals() overwrites the ones it needs separate.
WalSndLastCycleHandler is genuinely different. WalSndSigHupHandler
currently sets a different variable from postgres.c, but that seems like
a bad idea, because afaics we'll plainly ignore SIGHUPS unless in
WalSndLoop, WalSndWriteData,WalSndWaitForWal. That actually seems like
an active bug to me?
Oh, and one more point: There desperately need to be tests exercising
"SQL via walsender". Including the issue of parallelism here, the missed
cancel handler, timeouts, and such. One way to do so is to use
pg_regress with an adjusted connection string (specifying
replication=database), doing the same for isolationtester, or using
dblink.
- Andres
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 24/04/17 01:59, Andres Freund wrote:
Hi,
On 2017-04-22 17:53:19 +0200, Petr Jelinek wrote:
Here is patch. I changed both SIGINT and SIGUSR1 handlers, afaics it
does not break anything for existing walsender usage.diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 761fbfa..e9dd886 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -254,7 +254,7 @@ logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, Oid userid, BackgroundWorker bgw; BackgroundWorkerHandle *bgw_handle; int i; - int slot; + int slot = 0; LogicalRepWorker *worker = NULL; int nsyncworkers = 0; TimestampTz now = GetCurrentTimestamp();That seems independent and unnecessary?
Yeah that leaked from different patch I was working on in parallel.
-/* SIGUSR1: set flag to send WAL records */
-static void
-WalSndXLogSendHandler(SIGNAL_ARGS)
-{
- int save_errno = errno;
-
- latch_sigusr1_handler();
-
- errno = save_errno;
-}pqsignal(SIGPIPE, SIG_IGN); - pqsignal(SIGUSR1, WalSndXLogSendHandler); /* request WAL sending */ + pqsignal(SIGUSR1, procsignal_sigusr1_handler);Those aren't actually entirely equivalent. I'm not sure it matters much,
but WalSndXLogSendHandler didn't include a SetLatch(), but
procsignal_sigusr1_handler() does. Normally redundant SetLatch() calls
will just be elided, but what if walsender already woke up and did it's
work?
They aren't exactly same no, but I don't see harm in what
procsignal_sigusr1_handler. I mean worst case scenario is latch is set
so walsender checks for work.
I think it'd be better to have PostgresMain() set up signals by default,
and then have WalSndSignals() overwrites the ones it needs separate.
Hmm that sounds like a good idea.
WalSndLastCycleHandler is genuinely different. WalSndSigHupHandler
currently sets a different variable from postgres.c, but that seems like
a bad idea, because afaics we'll plainly ignore SIGHUPS unless in
WalSndLoop, WalSndWriteData,WalSndWaitForWal. That actually seems like
an active bug to me?
Hmm I don't think good solution is to use same variable though,
walsender needs to do slightly different thing on SIGHUP, plus the
got_SIGHUP is not the type of variable we want to export. I wonder if it
would be enough to just add check for got_SIGHUP somewhere at the
beginning of exec_replication_command().
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 24/04/17 01:43, Andres Freund wrote:
BTW while looking at the code, I don't understand why we call
latch_sigusr1_handler after calling SetLatch(MyLatch), shouldn't just
the SetLatch be enough (they both end up calling sendSelfPipeByte()
eventually)?Historic raisins - there didn't use to be a SetLatch in
procsignal_sigusr1_handler. That changed when I whacked around catchup &
notify to be based on latches ([1] and following).
Okay, but why call both SetLatch and latch_sigusr1_handler? What does
that buy us?
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 24/04/17 02:04, Andres Freund wrote:
Hi,
Oh, and one more point: There desperately need to be tests exercising
"SQL via walsender". Including the issue of parallelism here, the missed
cancel handler, timeouts, and such. One way to do so is to use
pg_regress with an adjusted connection string (specifying
replication=database), doing the same for isolationtester, or using
dblink.
Well, there are some tests (the logical replication uses that
functionality) and it's not quite clear to me what all to run there.
I assume you don't want to rerun whole regression suite against
walsender given the time it would take in normal tests (although I could
see doing that optionally somehow) but then what to pick from there.
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2017-04-24 04:26:16 +0200, Petr Jelinek wrote:
WalSndLastCycleHandler is genuinely different. WalSndSigHupHandler
currently sets a different variable from postgres.c, but that seems like
a bad idea, because afaics we'll plainly ignore SIGHUPS unless in
WalSndLoop, WalSndWriteData,WalSndWaitForWal. That actually seems like
an active bug to me?Hmm I don't think good solution is to use same variable though,
walsender needs to do slightly different thing on SIGHUP,
Hm? You mean SyncRepInitConfig()? I don't think that matters, because
it's only needed if config is changed while streaming.
plus the
got_SIGHUP is not the type of variable we want to export. I wonder if it
would be enough to just add check for got_SIGHUP somewhere at the
beginning of exec_replication_command().
I don't think that'd be sufficient, because we really want config
changes to get picked up while idle, and that won't work from within
exec_replication_command(). And that pretty much means it'll have to
happen outside of walsender.c.
FWIW, while it's not pretty, I actually see very little reason not to
share got_SIGHUP (with a bit less generic name name) between different
types of processes (i.e. putting it in miscadmin.h or such). It's not
exactly pretty, but there's also no benefit in duplicating it
everywhere, and without it you run into the issue presented here.
Greetings,
Andres Freund
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 2017-04-24 04:27:58 +0200, Petr Jelinek wrote:
On 24/04/17 01:43, Andres Freund wrote:
BTW while looking at the code, I don't understand why we call
latch_sigusr1_handler after calling SetLatch(MyLatch), shouldn't just
the SetLatch be enough (they both end up calling sendSelfPipeByte()
eventually)?Historic raisins - there didn't use to be a SetLatch in
procsignal_sigusr1_handler. That changed when I whacked around catchup &
notify to be based on latches ([1] and following).Okay, but why call both SetLatch and latch_sigusr1_handler? What does
that buy us?
Nothing. It's how the code evolved, we can change that.
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 24/04/17 04:31, Petr Jelinek wrote:
On 24/04/17 02:04, Andres Freund wrote:
Hi,
Oh, and one more point: There desperately need to be tests exercising
"SQL via walsender". Including the issue of parallelism here, the missed
cancel handler, timeouts, and such. One way to do so is to use
pg_regress with an adjusted connection string (specifying
replication=database), doing the same for isolationtester, or using
dblink.Well, there are some tests (the logical replication uses that
functionality) and it's not quite clear to me what all to run there.
I assume you don't want to rerun whole regression suite against
walsender given the time it would take in normal tests (although I could
see doing that optionally somehow) but then what to pick from there.
So actually maybe running regression tests through it might be
reasonable approach if we add new make target for it.
Attached patch shows how it could be done.
Patch adds new make target check-walsender-sql which runs serial
schedule of regression tests using replication connection (there is new
command line argument --replication-connection for pg_regress as well).
Reason for running serial schedule is that the max_walsenders setting
becomes problem when running parallel one.
Note that the first patch is huge. That's because I needed to add
alternative output for largeobject test because it uses fastpath
function calls which are not allowed over replication protocol.
As part of this I realized that the parser fallback that I wrote
originally for handling SQL in walsender is not robust enough as the
lexer would fail on some valid SQL statements. So there is also second
patch that does this using different approach which allows any SQL
statement.
Thoughts?
--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
Attachments:
0001-Add-check-walsender-sql-make-target.patch.gzapplication/gzip; name=0001-Add-check-walsender-sql-make-target.patch.gzDownload
�n��X 0001-Add-check-walsender-sql-make-target.patch �<ks��������M��k�z!�sg+�&��8@&��-�@
(#�8�����IH�y���K�������>�R�E-�5��cM���i��vl�������C��q��u���($C�$�C4���GM�k/`�crM������[����E�E�s�!M��v������"�e�8�s�[��9�`��p5�L'�1����������&]�#�9��6�� ��G�F�g@�-%��hZ������sJ�o/H���D
'~��x�N(��x�~8cc��
=7�HBSMk1��4I|�7�I�w��a�?m�j��w�$"��%$�w$Z�lpD���M&nP�41]���!�I����������?�����O�$�������M(��� ���`n ��0�%�*]�R2�b�p"&R��� S��a�.X-C*C�x,/�R����(�)�$]����*�C���Yk45���r4���C���
9�$�]J�Y����tr����#!���2$��~]��;����h�� �i��������lNJa�."�44�k���g��`$�X��
g���c�#$4F�%����������������R�k�mY�"�Z���S0�����`�������x�v[^���m��t��6����7�y��4l���C����'�$�nHP<)�A�`7�k���xA����4ZX)mN\/G�L������A4�?!d��$k�5Rk� %��6�=���Ec�� ��]�u\;���,�}����������i�n��<}�������&�8�uA=��.1�2`@�V0����)��1{6�C��7�
�W<�2n�S�3m6M�4�I�T*P��T<D�1
��������k��od���4j�?��|��a�C,],B�Bay�� f��U��c�~��xSD�1n���W�0��7���2�����*'X�r�N7
��N���%�ER�jY�Zt�0�Lh���8��������h�������+���Qo�o�>��~ "/�K)��Gn4x�����}����GN}7��O*s���s�� �����'������v��1K�eK����r&���xk6uS�[:3�#�~9
W�m�����V��L����?�B���y�DD�$*5���*fI ��BCQF��C�`��������] ����X�-\�l��;7q�'4��K��Q��\�����A�;��Q���G��������7XA>�"�#�W'S�U�3�������}&W����0A$��\Hx��U�(oW�*�j!��|��7s2����S�7���g��4a3J
(��D�����7��+����2�]�NGk,Cp�������;x�#���0R�j�QI� t` ��>y��vH�I���� ���w�P�6�#{����~�� �1[�bp�'O`�����i����gH�wuV;|����[��8
������A�������u��
�Y�^���� ,���H�d�
.�L�
��9<Z8�"��B�"`�3."��~��
F�����u��t���szO ������n��,OL�V�%
A��������V���.�9 ��0�E`q`�w�X����
���7`-g���b2O���(���� %��t�����<���2��F��&�?����b���=� ���'�H�Y;|w}��[�{�S�T)"�iw8������J��Y�gw�d�� x��.���G���AwQx{_'�i�.�L<�%�jW�Np<��bF6��:��,h�,���
���F��e�Z��
�%�%���t��:���{x���W
����eu�$�V`��9��i�`n�a��lN��=�����j�v�~��^����P;��������=����u\������4�� ����������aR�
��4�i�V�L�gH��0 ����Qc�m���B�����|��1���%s���z`���o��">��n�A"�u����s9�)���:H3�s���9�|� s�1��bDqRX.Eq��q�,�eS�%�8&�c2{B��d��SP���AW�s!Y�X�������!�����a�6<�
�18�m�8&L=(=FM,#�����?�cJf��sX�
��|�&+X�$Z,�Y:�!Q��@��O�
�������- �w�
���yt�QB�2�8f����+����aq���0-e���N �����k��0�(����87Y-�1��wx�D�)�]Mx�8�y-�D������$�A �8Z�n��&Sa�]aq�T�`LY0��:# �|X�� ���K`o��k�{RYH�L!�I&C�9�V��0�Q���1�a52A��HRG�����q�>����=���^G�h6���H?���yk1i9� ���z-��X��G�l�k�l�Q��}!FT�`/
��f\@��#*$~��
�'��{ �������4X��r��Z,�Y�1���H���������:�� �6+��Q;�c[F���l�wt�#X���a��~AGb����2���*^�H.�@���������0u� ��)�4�R(1����I���c� b�{��l/!�[N��y��a��+���$��d������"�\N1��qM �a��q_�����y0�����6��6�m����5F�����a��e�5�L�7.����ri����A.��&:���������7��P�n��� 1�r��*f%��E����(G��F�+c�)�A�/q���� �|c��)�:�<�:2�@�`�a&�}?���s��pS�, dXub����i+{�dGP�l��2�)�AC���d�_�YN$SJ����`�
R�I28�db]���c��?�@��#|�q���� cD�x�uq��(&�u`_�#�e�>>�;�<�b��2[�/�{��2�Jc�� ��<�1dN�����+��E���E{�����f���MC�1h���"V�i�;�����l�M�z��mE���`��~$��Z5�
�['�����5��D�V�Kr���y�����/��*�[��w��e[LU���:�ct�GW~�U0x������W������/B�m�8{�� '���Z+9�5t�������'2TI�B���D�Z} ��4��6�WL�&A����La�u�:�=L#/K���,��,��+#?�
?����y����\Rv�7�s���]�E�Yq��o>6/����������iEz��.�����=�@�����AxV���_��������0y�N�������Q�,���=��~�c;Z�`�x���������7�Our�g? ��������Q��$d��H���hr�_�{����T������qNPd��*�����O,����[73�%l3��_I���M]��T���L�7��_|�^������������+~���W��-��;����:vS���64{k}������(���������}6�?��0Z�@U�0G?���Qn7��4���e�M��2���������4��x��e5�����$�=25����+!���1��.<��8E���O������3�����g,"~^�f�}��^w���B}�>v�)_�x�^��m����E��
�:���[,b�{:���/�H�O�c|M�������g+�at���#��H�;wQ|�����������~�����9�������{+��M� �z���W��7�"1!������R��#��Uo����h_���o�zN{���$"u��1�7���k��k��k�V�e�]��]��]����>�����]��]��]��]��]��]��]�?��G�N����:�U�U�z���A0x'?H��x#~���OS,���A���Zw[�v��{�>}�R�����#G����`X/FJh���3wg/$����w8�����f���C�s � r����X���$z����&�jm���'����^��W[��m������D�f���f�"��{>D���,@���a�IsP�N���hZ�j�����N�;\H[��7���D���i�f+o��N��� �����$7*Q��q5;o�_1����
,���_I��J�X�� �����~�^���������O1����JT���4�v���!bd%l� x49Q��}�2-�%
�{��3^Yo��U�����������m��)�L{��>$���#����cO��X���.��)�
��@@K@5C�;��S�J�m�F�;�!JhHDu�[/w����h��D�mG>'c�"��X�V�����{�B����Fl+O�l�- l��:O/7�ik2�8��\w��F�4���(W�$���Mm�t[�=nve!O$U��"l�o%�^�2!�K6�J6�#
P�����
�/J�)J�YD�����@XW�p_�(�qds�A�4�92]��%��4v���U�:M���.�-��6��H ����}�{*i����e�� ��<9n�Nx����� tM �@U�]�N�����.TB�����9` ������)����Y)\>���67�6��[�?/J�i��u*t��^X[�"/�>(/K#�!�������h��U�<]�l=:S�{�*M�7�����,��-�>�}O��~�;�,��SW�z�����Z�{����[2��X|�X ML���U�#Q��3�l�������,[�9�B*m���+!�sDz��u��fJzQn�uI_^���Q���l]
��)w��F!�fb"FJhILy_�"G�Rq������6D�K{>�� (r�V�z�J����>