[PROPOSAL] VACUUM Progress Checker.
Hello Hackers,
Following is a proposal for feature to calculate VACUUM progress.
Use Case : Measuring progress of long running VACUUMs to help DBAs make
informed decision
whether to continue running VACUUM or abort it.
Design:
A shared preload library to store progress information from different
backends running VACUUM, calculate remaining time for each and display
progress in the
in the form a view.
VACUUM needs to be instrumented with a hook to collect progress
information (pages vacuumed/scanned) periodically.
The patch attached implements a new hook to store vacuumed_pages and
scanned_pages count at the end of each page scanned by VACUUM.
This information is stored in a shared memory structure.
In addition to measuring progress this function using hook also calculates
remaining time for VACUUM.
The frequency of collecting progress information can be reduced by
appending delays in between hook function calls.
Also, a GUC parameter
log_vacuum_min_duration can be used.
This will cause VACUUM progress to be calculated only if VACUUM runs more
than specified milliseconds.
A value of zero calculates VACUUM progress for each page processed. -1
disables logging.
Progress calculation :
percent_complete = scanned_pages * 100 / total_pages_to_be_scanned;
remaining_time = elapsed_time * (total_pages_to_be_scanned - scanned_pages)
/ scanned_pages;
Shared memory struct:
typedef struct PgStat_VacuumStats
{
Oid databaseoid;
Oid tableoid;
Int32 vacuumed_pages;
Int32 total_pages;
Int32 scanned_pages;
double elapsed_time;
double remaining_time;
} PgStat_VacuumStats[max_connections];
Reporting :
A view named 'pg_maintenance_progress' can be created using the values in
the struct above.
pg_stat_maintenance can be called from any other backend and will display
progress of
each running VACUUM.
Other uses of hook in VACUUM:
Cost of VACUUM in terms of pages hit , missed and dirtied same as
autovacuum can be collected using this hook.
Autovacuum does it at the end of VACUUM for each table. It can be done
while VACUUM on a table is in progress.
This can be helpful to track manual VACUUMs also not just autovacuum.
Read/Write(I/O) rates can be computed on the lines of autovacuum.
Read rate patterns can be used to help tuning future vacuum on the
table(like shared buffers tuning)
Other resource usages can also be collected using progress checker hook.
Attached patch is POC patch of progress calculation for a single backend.
Also attached is a brief snapshot of the output log.
Attachments:
vacuum_progress_estimate.patchapplication/octet-stream; name=vacuum_progress_estimate.patchDownload
diff --git a/contrib/Makefile b/contrib/Makefile
index bd251f6..f3d3fe6 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -47,7 +47,8 @@ SUBDIRS = \
tsm_system_time \
tsearch2 \
unaccent \
- vacuumlo
+ vacuumlo \
+ vacuum_progress
ifeq ($(with_openssl),yes)
SUBDIRS += sslinfo
diff --git a/contrib/vacuum_progress/Makefile b/contrib/vacuum_progress/Makefile
new file mode 100644
index 0000000..5fa5fc4
--- /dev/null
+++ b/contrib/vacuum_progress/Makefile
@@ -0,0 +1,15 @@
+# contrib/passwordcheck/Makefile
+
+MODULE_big = vacuum_progress
+OBJS = vacuum_progress.o $(WIN32RES)
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = contrib/vacuum_progress
+top_builddir = ../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/contrib/vacuum_progress/vacuum_progress.c b/contrib/vacuum_progress/vacuum_progress.c
new file mode 100644
index 0000000..0c862cb
--- /dev/null
+++ b/contrib/vacuum_progress/vacuum_progress.c
@@ -0,0 +1,126 @@
+/*-------------------------------------------------------------------------
+ *
+ * vacuum_progress.c
+ *
+ * IDENTIFICATION
+ * contrib/vacuum_progress/vacuum_progress.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "commands/vacuum.h"
+#include "portability/instr_time.h"
+#include "fmgr.h"
+#include "funcapi.h"
+#include "storage/block.h"
+#include "access/htup_details.h"
+#include "pgstat.h"
+
+PG_MODULE_MAGIC;
+
+extern void _PG_init(void);
+#define SKIP_PAGES_THRESHOLD ((BlockNumber) 32)
+
+typedef struct PgStat_Vacuum
+{
+ instr_time start_time;
+ double elapsed_time;
+ double remaining_time;
+ uint32 total_pages;
+ uint32 scanned_pages;
+ uint32 vacuumed_pages;
+} PgStat_Vacuum;
+
+PgStat_Vacuum backend_stat;
+
+/*
+ * Calculating progress at the end of every page scanned by lazy_scan_heap.
+ * This can be improved to calculate progress at specified intervals only.
+ *
+ * Vacuum Progress is measured in terms of pages scanned
+ * versus total pages to be scanned.
+ */
+
+static void
+calculate_progress(BlockNumber vacuumed_pages, BlockNumber pages_to_be_skipped,
+ BlockNumber scanned_pages)
+{
+ uint32 percent_complete;
+ instr_time elapsed_time;
+ INSTR_TIME_SET_CURRENT(elapsed_time);
+ INSTR_TIME_SUBTRACT(elapsed_time,backend_stat.start_time);
+ backend_stat.elapsed_time = INSTR_TIME_GET_DOUBLE(elapsed_time);
+
+ backend_stat.scanned_pages = scanned_pages;
+ backend_stat.vacuumed_pages = vacuumed_pages;
+
+ if(pages_to_be_skipped > SKIP_PAGES_THRESHOLD)
+ {
+ backend_stat.total_pages = backend_stat.total_pages - pages_to_be_skipped;
+ }
+
+ percent_complete = scanned_pages * 100 / backend_stat.total_pages;
+
+ backend_stat.remaining_time = backend_stat.elapsed_time *
+ (backend_stat.total_pages - scanned_pages) / scanned_pages;
+ elog(LOG,"%d pages vaccumed %d scanned_pages %d total pages\n",
+ vacuumed_pages, scanned_pages, backend_stat.total_pages);
+ elog(LOG,"%f s elapsed time %f s remaining time", backend_stat.elapsed_time,
+ backend_stat.remaining_time);
+}
+
+/*
+ * Storing VACUUM start time and total pages to be scanned
+ * in a global struct shared across backends.
+ */
+static void
+initial_vacuum_stats(BlockNumber total_pages)
+{
+ backend_stat.total_pages= total_pages;
+ INSTR_TIME_SET_CURRENT(backend_stat.start_time);
+}
+
+/*
+ * SQL callable function for creating a view displaying VACUUM progress
+ */
+PG_FUNCTION_INFO_V1(pg_get_vacuum_progress);
+Datum
+pg_get_vacuum_progress(PG_FUNCTION_ARGS)
+{
+ TupleDesc tupdesc;
+ Datum value[5];
+ bool null[5];
+
+ tupdesc = CreateTemplateTupleDesc(5, false);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "VacuumedPages",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ScannedPages",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 3, "TotalPages",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ElapsedTime",
+ FLOAT8OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 5, "RemainingTime",
+ FLOAT8OID, -1, 0);
+
+ BlessTupleDesc(tupdesc);
+
+ value[0] = UInt32GetDatum(backend_stat.vacuumed_pages);
+ value[1] = UInt32GetDatum(backend_stat.scanned_pages);
+ value[2] = UInt32GetDatum(backend_stat.total_pages);
+ value[3] = Float8GetDatum(backend_stat.elapsed_time);
+ value[4] = Float8GetDatum(backend_stat.remaining_time);
+ PG_RETURN_DATUM(HeapTupleGetDatum(
+ heap_form_tuple(tupdesc, value, null)));
+}
+
+/*
+ * Module initialization function
+ */
+void
+_PG_init(void)
+{
+ vacuum_stats = calculate_progress;
+ vacuum_stat_initial = initial_vacuum_stats;
+}
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index a01cfb4..6e6bab0 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -157,7 +157,8 @@ static bool lazy_tid_reaped(ItemPointer itemptr, void *state);
static int vac_cmp_itemptr(const void *left, const void *right);
static bool heap_page_is_all_visible(Relation rel, Buffer buf,
TransactionId *visibility_cutoff_xid);
-
+vacuum_stats_type vacuum_stats = NULL;
+vacuum_stats_initial_type vacuum_stat_initial = NULL;
/*
* lazy_vacuum_rel() -- perform LAZY VACUUM for one heap relation
@@ -470,8 +471,13 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
indstats = (IndexBulkDeleteResult **)
palloc0(nindexes * sizeof(IndexBulkDeleteResult *));
-
nblocks = RelationGetNumberOfBlocks(onerel);
+
+ if(vacuum_stat_initial)
+ {
+ (*vacuum_stat_initial)(nblocks);
+ }
+
vacrelstats->rel_pages = nblocks;
vacrelstats->scanned_pages = 0;
vacrelstats->nonempty_pages = 0;
@@ -520,7 +526,9 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
vacuum_delay_point();
}
if (next_not_all_visible_block >= SKIP_PAGES_THRESHOLD)
+ {
skipping_all_visible_blocks = true;
+ }
else
skipping_all_visible_blocks = false;
@@ -559,7 +567,9 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
* following blocks.
*/
if (next_not_all_visible_block - blkno > SKIP_PAGES_THRESHOLD)
+ {
skipping_all_visible_blocks = true;
+ }
else
skipping_all_visible_blocks = false;
all_visible_according_to_vm = false;
@@ -1062,6 +1072,10 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
*/
if (vacrelstats->num_dead_tuples == prev_dead_count)
RecordPageWithFreeSpace(onerel, blkno, freespace);
+ if(vacuum_stats)
+ {
+ (*vacuum_stats)(vacuumed_pages, (next_not_all_visible_block - blkno), vacrelstats->scanned_pages);
+ }
}
pfree(frozen);
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index e3a31af..a700b94 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -192,6 +192,15 @@ extern void vacuum_delay_point(void);
extern void lazy_vacuum_rel(Relation onerel, int options,
VacuumParams *params, BufferAccessStrategy bstrategy);
+typedef void (*vacuum_stats_type) (BlockNumber vacuumed_pages, BlockNumber pages_to_be_skipped,
+ BlockNumber scanned_pages);
+
+extern PGDLLIMPORT vacuum_stats_type vacuum_stats;
+
+typedef void (*vacuum_stats_initial_type) (BlockNumber nblocks);
+
+extern PGDLLIMPORT vacuum_stats_initial_type vacuum_stat_initial;
+
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, RangeVar *relation, int options,
VacuumParams *params, List *va_cols, bool in_outer_xact,
VAcuum_progress_report.PNGimage/png; name=VAcuum_progress_report.PNGDownload
�PNG
IHDR 8 z B�� sRGB ��� gAMA ���a pHYs � ��o�d ��IDATx^����T5��{��FZE�EmAAE@TZ�ZFE]"�6"HC����@���I�y@D@A&���O~7{�S��IU�:���f�Z*;����]��|I�� " " " " " eB��)�z�" " " " " "`$p� D@D@D@D@D@���N�4�[��O>���O�������-L���L�b.����+s�d��1��k��-���@���B�3��J�|yWL E@D@��@$ph���������/�k������]w�e~���
���1�4k��������7�>�l�U����y���L�z�����j���~��o��?$�+��b.��b��?���{��f��EQ�+W�47�t�9������}��
�~��GM�F�l�
��C��#G��k~���H8���\����F���?��E��>R�g��U�~ia��%�_��W)g�:������������������k,G��i�C��*������Uh�B�\��O!�RZ��#,p��s�������K���Hw���_6'�p�y�����u��;��cy��*�����os����w�}�|���VD<�������G���S���?�1co������O���{�=3b��M������
?��g�6g�q�y���mzD�_|Q���gO��k�(���+Z�%p�������J�K����w�I�&�+������>����O�<�����R%(A��fF/.L�:��r�)�8'����2O>�����;��M�41���?�lqu@��_��m���#T� ��r6�t��!k��=j���o������?����������13��ys+�Bm������;w6[�n��<M����k�U�V6-3l}��1��c�R>�A�v������+����W���w�n����{ �C]������3l���s�F�d��-^������a��f����yj��}4C�+���|�����������7�P�L��+_���������|������2d�y���s�[&����~!��{>�����1k����K/��|���Q�
M�w�^s��7F��W��������>�� �'�|����?���_���<���_~��y��-�[e�C���3���8|�o�>��|�q%�]���>}�5����������3�p���q�5v���l#��a�r�Re��g���k���;wZ�:FTC.v��4��m30�[���<M������z���_�v�l. p���-[�P��������^�c��M��7�4u��
6�\CF���!��=������J���B�0J��?��|��������x�I��������,D�d>����?!y p�y}��������������������/i�
�����N�������j�����o��,�.f�x��������5" " ��@��Y�b�5H6l����{��@�h�� \�|2EO1�+�������0���L� ��/�w�}g�����q����
FDfH8�'O6�w��>i����_oe��������"��G}%g��V�Z�����������G�!>
��~��~��~�V~_�(+}�J0���@s�Q�L�S�N������M�K�I����=z��*p2�_�|�'$=� p2E=�����������|�k�
38.���Y��Oz.����z�ry~B�_�����T�*p���ok���=�<�q�y�|N��.�����l3Di7w68�����rf`��>�>����X#���p�Yqc��>_}�UV-'p]�4��� ���"1���������@���OZ�}�s}��+XU���n��\~^z�%�+��}������+[��U������mU
8�����.�k��=}���Ik��=�~ie���Q�f��i�6mz�|���'�2�2�����]#" "P� ���sW����NU �\\h�5�/�3����%w�2��ZD�\�\��<2��Q��1Lr�Z�c
��3��M�������� I��r�z�~��Y7-\{0��<��(9��g����kaf�I*��|�@#���)��l�����M�K���?.e�v�?�a�E���q��������������]z��x�����/M���!���i�@!��s�Me�|�������'���:��C H��J�1��� >�,;vlT�$�SU�`,g�d �����3�_p�&n@�5>���b��
�>0n\`�3�������v=\��w�t9.8� �`�����'��!x��5;�k.m�8�.,[����Z�����������#��*p����Y��3p}�i$_�uy���C��&P����>�hc�����&p���F�kr��.]�������C�W�|J����w.j���~�U>.j�����t����@i� p��)s�b7���%�Dc������\x�����B��1J����6(��0~�x�M4;4�m�t_zvh����3��h���0`�����~����p�� �
\ef��e]�2nc�tg��C�|��u31�+ych�& i��ly��5ef
k���m��v��-Z���w$��3;������/�g
��,\���������-����+��|���@E�Q~y��g��a����W8�(� ���������������}������gsQI��|�����/=�I��~��y>��q���5�C���^q�v&�X����������>*��!��o�
*���0�������[#/X��H/3 �"F]��X�D����t�g��}���"Ov�:������v��Fg���F�1�H�$��=��s��u������l�w_�s���60�����K�a��OX�C�;����:��m{X�����n�G$#Y��)p��_~�u]��&�W~_�p�cq:�F�s5�������oM����J��K�������}������CNH�������|�}'��B���|����Sh�={�D���i��n���5����k=t����@i�NiS�+w��a����@�`��n���~AUB�I@�F6{�UZ���D%G ��7�x��:�$3�le� " " �H@�[��I�6��\m�� �����k���#�M�UP��G@����j," " " " eK@�l�V��G@����j," " " " eK@�l��4+�����7���������������T&�H������q���!�<��s��{q�b�3>2�:�������<8������)���������).�7��7�~����~���m�6J�a�|�95!��L��y�5�4j���[\r�%�����O��.X�|�����L�:u�Y7w�y��:x���+�t��a�|__|�P>���K�y�}h�ND@D@D@D@�D�����
�w���f��if�� 6��-[�_|a?7�p����k��o��9��C�a�-D�u������={F���q�6L�n�:��U�V����IJ����8!�+fZ�z���m�n�s�N����$���u+�:����fI� _|�P>���3'N�\����������@N��a$cz��U���z��3�����M��}�����>������e��/f�T�N�����IJ��l��!�q��gZ��n���S����7
40��O���5k��W��=���4���w7�:u�Z,�����������k������>|�
2f�N9���Os���([_��������E@D@D@D@J��8G��nM�����,M 4k����3�,X�����-"p��k��cF�m?�
����[����?�-pZ�li�gez>.0���I|H����'U����q�W�I�&s�}��g�6mjg��ec�N\���]��j����:�?�@��6u�T��t�E�kN��E����v��f�������@�
6�E���\�����\�pS�=m��M����n��c��f��%'pf��m]�\����4������#�-*��I���� 37������gN>�d;�����['�%t��������'�
��������9��
a\<8X�0*��
X������� ��54����I���o\�Z�ha����IJ8�����-p��
����q���u��U����.���*���?�K6����5k�D� ��n���vC����{�:��'��M��%K����"P�t�b
tv`��l"'3��F^K�.5|�AV��[�����G�g�a.\��R���
��6e����T������u�&��������m����L��G'�����@��Y�n�5��M� �#j�V�������pScb_z�C6��`�kp�j��
����m�C���)�"��#G�[o�������1"*V��]����;'���//^l���� i�q��A�h�uQ�/�t�I�.j����w��]a�+�\�ND@D@D@D�<D����8����������� �p���}���Y,��K�N�m��]1����&}�E�{��S>��k<V�\ig�6lh�-[a��V�����W/��f-�:���+����CA��?�qH�d`��A�I�&���>�[���@���xwvkc�r��I 8?���`�Q}v���Ed�l.f�����E1�I��&]>�l2� ��
1���$}���,�R8�IN�A��|��/b��%�]�\�=z��U|�u�Va�#->����$p��_�~���n�,3W.���um�����D@D@D@D@j&�D���C�����C��U���������@�$ �S3��,k�������e%U)�T8� " " " " " eC@�l�R��Q(8e����������������@� ���l����dD�� L�2E���p�}J�q�P4�~���' ����I
������h�s�]w����3f�f���'�?�|����VY�7l�`:v�hN8�S�~}{��o��f����q���-����VYa���Z��
������b���G5�5��T7h��:�9r$B}���G���7�|��6���!P,����^��\��?w]R�����j�R��k�B�WZ�}������Ro[�OD�"�`���C�s�9�����K����s���_������3���3����y��G����_l']�~�����m��y�{D~�?={�4]�v������
�����P�T1��a����7�c�����V�u���O�
}���4R��H�e@O�4�\y��V,�����j&�/����X�S����k�B��N�� �Oj� ��LH�z��xqa�����y��g�u�y��'��v��a�Tf��u���_�re����?o�4i��6G���<���.FE��}M�V��}�.]��]���01b���������\���W/3d�;��,�����@����js��'Z�\��/�k�������I{����o���&���o��=�W��]60i�;|�����^���C��l/^lg7�7on6lh&N�h���}�h���|�N�����w����a���:D�8|�o��y���l����z���\@�����x��6��|�����������Y*�2����k��56������<h����W~��?_<���1c����93z?��O_���{�`q|�������6o�l�y����8��g�?�sI��_H�����}��_��_������kK_����}"[�J��!�������������=�����:*^��@�����A��'�D������w��03��_~���O��-�[eW>)�O�nj��u��s��5��v�A��^p���e�=H2>��F#���m30�[���=�����z�`�1�|�r{
b�n����of�L.��� @\����u��wW�!3���w�}�i����]�������y�I'��B9i���a6��������!}Z�C���\<6n�h�?|��( Q��&�5j���������/�~�}�v�w��kg�����(����k�J� ����qV���;w�4�-�<CC���
��f�_�}���8������0m�i�&��!�re
�:�O?�4Q�$����I��k_���_��b�Ou�|���w�"������i�.���������������~��r$$pV�XaPY����5�@�G��}������~���]�~2EO1�����5�X��hj��mm���]��f���9�'/�A�Ei��q�g~��'{O��>�(�g���A�'S����{�\~��Y����t��������V>~�0�_}������1C��*��Z�~f�:u����u�&����!������u���'�>A�C �5`���o�ag!��kg4����2�����!*��q�?�0������3#��e��G�Q�������H�.^~.J�!�>���?}|x�y������)p��u��NZ�I�������Of����{��WE�T������x�/���������w.�_���<
qq����>�F��@�
�����?��=fw�"`�12���a=r������pc��������c��W����*��n��t7������nJ4�B�� =zt�-�����C.?�������4�0�����=�\�^z�%{�4��,I?P!|�#����}�70��+��b�>��
�%3-c�e����0s�,
�,������f]h��K%��6 ��������m�=n������ �N��"��i�'}���8i�����ef���T��av������m�I'����OkG_��������WZ|U�Ou~�|���w�"��[�������~���~�|��<
8I���]����w���r#$p|.j�]�;U)p�/39�}����7�l����i��4*?pn��g�*S���N��Q�������c�V>�T��a-!��+�O�����/��Q<����M�fChH�C�gS�~��Y7@\�g�y��>T�����(��~�@u�%�{��f�������Qn�����k|�/�����������$ ��3���8��q�uf�%pp=dP��=|ps������f���O�ly��_��^��WZ|U�Ou~�|�������w@�NH����
�����K���N�N��@����c-i��|����N16����s�����*D1�w�� mH~�0�\X�lY�:u���f�&p|.j��}sB���u��\]���d�������������p�������OZ�C���!��Nb�k���$�?�|e���l�8�E����������/^\<�w���������{�������!�7�|s�MPxW9�>����C���$Q��8�s�����3��7� \d��x��'��a3�?������WZ|U�O���W�?�����/���|}��'��dsQ��~�����~?B�_��?�~�F��@���V��)�QIfX�+nW\pA�]����0F<Ef��lc
���}�
�#�|���=nS�^p��@�����n���(V���f����6��v[��� �H�f����?����@ #������Y�\� ����I��}���C,�w��}$e��u Z�ha��:n�q!����>�������d��+��Y�l_p ������F0�K���rNTF&���Q{�������v�W�ut��u���W0�}�g/���
kV��(�<O�l�A��au!��������'�7\������K�NH�b}�7"�����8�l3]�|���>��|���?�}}�/_����>����vN���k
�_I�)�������KJ��|��g����WW��@�� p2���nc��m����o��x`a;F.#� Qg�U,��� �{�����z��m��x�!�0�0N�m��a�h�y��w�;Z���L�mVYC���.`8���3 \>��c��Mtf���E
C�+X3�M8i|]�9���E��s(_�}|����P�����)�D7������7���;V.po_�{���-���f������gO��q�6m�}�P~�_�/��-�3��s�l�9���W~����g� 3��9������ ���a��OU _��l����C�?���k_���_��)�������3�s�_i��������x~I�}�����{w�S����x(��)�
���yW(�M�Z�|�����[qS��@���Wf
�cu��9��"P$p��_p���1��oq���l2�No������1M�<�~����J��/��PQD ��N �B_p������oq\x�����5�QW#P��I�_�R�J�_�-�r�@2 ��K��i�\6c��Uq(18%� *����������@�$p�g��" " " " " %F@��D����N���RD@D@D@D@D��H��X��8" " " " " ������R����������� �kGD@D@D@D@D 8��SJ�# �Sb
�������������O@'vJ)" " " " "Pb$pJ�AT�� H���N)E@D@D@D@D@J��N�5��#" " " " "�? ���)����������@���)�QqD@D@D@D@D@�' ��?;�(18%� *����������@�$p�g��" " " " " %F@��D����N���2_}��i���9��������GJ"" " " " �"��k�.s�w����/��N0�_~��;w�My�-��?��OY?�^{m�����?S�~}�����}�����������������OGy�7��7�~����~���m�6J��7����������#�5�4j����/������{���/_n���*S�Ns����;���F<x����7�������w�����es�����n���������~
M��D@D@D@D@D �@$p���js��W��k��i��� &�L�l�b��������5�\������>��cs��g�s�9�������!�(={���u�������9���M����<[�je�����N�0k@�q�R� �y^�z�j+6�m���s�N����$�������O4C��s�]w�e���/>�h���kg&N�z����X��H:���U���{��eg<�������}����|0�5I�8��0�_�*!�'�]v��..p��;��82d��E\����V?���c��Tf����M�
�����lg��e���gx.���������S�b��/>���3}���q���[A���)��b���c:e��w�}|uS��������@�����#��i������ �f���9s���/������c��1c�����'W�3�|+~����N��-
����A������!�/ Q0y���
�4��<���
3i��c.����L��M���l���V_���X�Z?]'" " " "���\��N�j]�.��"�q��o�$PX�R�vm�w�^s����?��l����<�fp2G���7��+nj��m���������`8w�����1����������=>���w��}vvd��EE8i�C�q6��@c���W_���7o�9�����/>~o ����u" " " "P�*���g�3s�L�*�q9x��`���<�+\`��s�g�&p2���_��&u��qMk����>s')}\� $��o���)V7@�Fh���f����V�Z�r�����N�P.� ���Ye�8������
��C���D@D@D@D@��@�6�K�,�F6�w�@����5�����9���P��Z�t�����
�fp�=j�8��p��h���UEW`��)S��
����4��p��[7�E
���]��m���f�P>8��t��������@>��u��Q�l�O �HQ���_����.�������@fs]��vP6l��
�mR>wM1��9��z���w��f��Q�B�v���t��9��>�}��x�b�>l�MH����
��C;_��}���NJtQ�����{��
3_���u" " " " �A 8�����A�l��7nl�?� �3�h��g�ba70_z'p�m���B�����4��.j�70f��8�\��r�J;���aC�l��[_��>�����u�z�M4k�\@�!.V�Xa�O�*������C�&�
2M�41�}���*�M�������[[�+���������L��y�������#/B 3ds1����-��N�6���e��n���t�'�3eA����AL"p2J
��0e}�E .a������������[�
3i�!�C�$��������}w;f���r���k���]�� " " " "P3 $���L�uu&�l���D@D@D@D@j& ����eYk6���%���,+�J�����������Q(8e��������������������������@���)��TED@D@D@D@D@$p�*� [O��6z-�0e���l'=f��Y<
"P���B��N�<K�|�������8p��,����/����>w�u�a[�x�1c�i���=p����7�>�l��2 v�z���L�z��0�������R��%!�_y�s������=�\�h��(������i��f�����W����� '�|�����}��+Z��#�,pV�Ze���,Yb����r��}��W _z_����5�4m��>;g�u�y�������9U��p�r�;<�:����/����:���SH��VD@D����9��c��w���V�:4���/�lN8���s��u���w�y�<��#UV�������O7�������
���~:������:u��CG1��z�-����F����{f��6>I�����\�>��������>��E�P��p=Y����d���x_��`�^x��X��L�6��t�I��'���B�����������kT����}�kz|�����T��!$p� af�����S���'�3*�������������I���3�WDXh��o��m��<�Y��6lXbq|���KK��'�m}����o��7o��
��@#�hg�l������[+$O8����i���M�b-.����J[>�A�v������+��W~_�v��mn��{��`��������7�3�F�g<���]����x�b��Q#��a��f����yj��}4C�+�����Sh����������^s���g-���GM�����y�*�?��S�^�z�!C��|�>G�eN�4��1��B���|��/�O�c���[�^z����o#~����w���������rz~|���E@D@�� ��y�fk�}��'Q�>��s�������+������l����Uf8t���?�*.0��w����������#�v��f����8��b���<&�4�����F..;����M��?� p��{+��]0n�8kd�]��������1�}�Qk��f��mf���u���� �_|�`d���_�v�l. pp���e�uD �G�}�������6m2���[7�@se���� ��P�?����P���i��
I�K���_�~�7^>� }�����)��3�0O=��9x����n�����i���8$�Q�_1�@�b� 1��w�����?�����,9/T������u" " ��@������a���f����r\L�� ��)z�!p\YV�^��`�S&~�}�������y]x���8��eF#"3$x����y��7�����c�,����mr���&-��~�3c��H>�����GE��}�U�V����Q���G�!>
��~s�q���~��~�V~_�(+}�J0���@s�~���v����S'������,�����K����"px&�ON�e�����7������]A8���8_�!p��?[�d>��4����f+k>����4r��������/�����T?�*p���o 0��l� ���!n��#���������_����m�(���;n?�|�O�����s�����_}�UV-'p]�4��� ���"1�������a��DI�����W>���r��RUi��{���qH�����^2����'�����������Q���K*����3�����OVe�w�C�������~���'/�����&PF�k���vS���Oz���]F�@�\����x��G H��\���?�. v�J���B���|���=g��(�[���"�g��Xh�� ����������u(>j�h�GHp\6��x�$�����pK�M��3�<3J��y��g��cg�������4���:�R0�X��+�����?�<}�}�����?����M$�<�nk�:We�we��y���)������|��� �\�9w(�����Ne<?���x��G H������M��fa8�W.$ ���d c9�&I��\D����.0q���a�m�������`������2����p���{P2\p�An�����Op[C��kv+m�8�.,[����Z�����������#��*p��� M
Ikp�F�1�|�i����o��?I�PG\�n��6k�g�Ic�/��%��*��+C�����O��<���8�|�;���?�*�R~~B�1]#" "P}T8����]��f��m�1�����gG!��y����l�m��b����ga�h��M�&:�������KugD�C�t���<�������g�43@��&��G��W��������u91�+.@� `=Hh��<����$�$Q?�����E�/����h�fv�q�s��~��>S��.c���v]��W_mn���({_�}�������B�Q~y��g�)v�:|�p�����������N�������}����}��7[�4\��;&>��5�M�7��R���/I������!��k�|���&i3@��^q�v&�X�������/�����T/N�A{��m��6�,�f&c�������2���TF��)�g`��D����t�g���K�,y����'�h�O���f�!?�j������f��L3Kn�W�������s���60�����K�a��OX�C�;����:��m{X��K~������d�!��2"�����D���+�u,^G� ���|�y����&�~���1�}.����k__��=����������M��)_����,Of(���8i�����#���B����'�f�M�6v�xO��T��\���E@D@J�@$pJ��*]�`
3[
" �O��2�u�V�U E@D@j$ ����Wi ��k�H�O?��ns���l��L,[Y+�����@)��)�V��e������*Wl0�9`���Z8r��jSvTD@D�����ym����������@���)��U�D@D@D@D@D�����ym����������@���)��-��q�I����y'l�� " " " " �I 8�v�2w�q�=��sH8�d����^������N8+�~��6��p!$�u�]�������s/�Nq���n��q����?�����m��Qz��;�� )_eB��k��Q�������?�x�u_w�����UW]e���c�����;m���m]9��C�;���C�����@�\vdR��$ N�g'+��k��i��� &�{m��%:}��n0�\sM����7G���Gv�aQv�q!$=�g��Q���s��������[Gy�j��~8I���a����'�|� =3���W[��m��(j����;D�I|�g�V :t���k9���0����|��kg&N�z����X��H:���U���{��eg<�������}����|0�5I�8��0�_�*!�'�B�wq���� ���!C�-�'~���q��;��2����n4h`�O�e;k�,S�^={��i|�w���x���/>������^{�]�E����V�1�w�)��>}��C�E������h_�/" " " "P:��9r��uk?~��di�Y�ff��9f�����l��3v�X3f�3z�h��U���?�����9o���eKC=+;`��qa��w�xH��@BL�<9k�|��N�PW\q��4i�1��w�}�i��v��Y6����/�eX�� ����c D.jS�N�.N]t������\
kYj��m���k8`���a�1Y� ��u>n]�3�q%�M
��M�6#p�����;�3f����={�u�s���gt��������,Z���'�h7�&ph���OF�7o�9�����/>~o ����u" " " "P�*���g�3s�L�*�q9x��`���<�+\`��s�g�&p2���_��&u��qMk����>s')}\� $��o���)V7@�Fh���f����V�Z�r�����N�P.� ���Ye�8������
��C���D@D@D@D@��@�6�K�,�F6�w�@����5�����9���P��y-]��|��Y�o
38G�5g�q�Y�pa��ZH���+����)S��R�C_f8�������K^�.j�����3�( �PR�ND@D@D@D �g��u�(f6�'