@@ -61,10 +61,11 @@ typedef enum {
61
61
} aqo_queries_cols ;
62
62
63
63
typedef void * (* form_record_t ) (void * ctx , size_t * size );
64
- typedef void (* deform_record_t ) (void * data , size_t size );
64
+ typedef bool (* deform_record_t ) (void * data , size_t size );
65
65
66
66
67
67
int querytext_max_size = 1000 ;
68
+ int dsm_size_max = 100 ; /* in MB */
68
69
69
70
HTAB * stat_htab = NULL ;
70
71
HTAB * queries_htab = NULL ;
@@ -642,7 +643,7 @@ data_store(const char *filename, form_record_t callback,
642
643
return -1 ;
643
644
}
644
645
645
- static void
646
+ static bool
646
647
_deform_stat_record_cb (void * data , size_t size )
647
648
{
648
649
bool found ;
@@ -656,24 +657,35 @@ _deform_stat_record_cb(void *data, size_t size)
656
657
entry = (StatEntry * ) hash_search (stat_htab , & queryid , HASH_ENTER , & found );
657
658
Assert (!found );
658
659
memcpy (entry , data , sizeof (StatEntry ));
660
+ return true;
659
661
}
660
662
661
663
void
662
664
aqo_stat_load (void )
663
665
{
664
- long entries ;
665
-
666
666
Assert (!LWLockHeldByMe (& aqo_state -> stat_lock ));
667
667
668
668
LWLockAcquire (& aqo_state -> stat_lock , LW_EXCLUSIVE );
669
- entries = hash_get_num_entries (stat_htab );
670
- Assert (entries == 0 );
669
+
670
+ /* Load on postmaster sturtup. So no any concurrent actions possible here. */
671
+ Assert (hash_get_num_entries (stat_htab ) == 0 );
672
+
671
673
data_load (PGAQO_STAT_FILE , _deform_stat_record_cb , NULL );
672
674
673
675
LWLockRelease (& aqo_state -> stat_lock );
674
676
}
675
677
676
- static void
678
+ static bool
679
+ _check_dsa_validity (dsa_pointer ptr )
680
+ {
681
+ if (DsaPointerIsValid (ptr ))
682
+ return true;
683
+
684
+ elog (LOG , "[AQO] DSA Pointer isn't valid. Is the memory limit exceeded?" );
685
+ return false;
686
+ }
687
+
688
+ static bool
677
689
_deform_qtexts_record_cb (void * data , size_t size )
678
690
{
679
691
bool found ;
@@ -690,9 +702,19 @@ _deform_qtexts_record_cb(void *data, size_t size)
690
702
Assert (!found );
691
703
692
704
entry -> qtext_dp = dsa_allocate (qtext_dsa , len );
693
- Assert (DsaPointerIsValid (entry -> qtext_dp ));
705
+ if (!_check_dsa_validity (entry -> qtext_dp ))
706
+ {
707
+ /*
708
+ * DSA stuck into problems. Rollback changes. Return false in belief
709
+ * that caller recognize it and don't try to call us more.
710
+ */
711
+ (void ) hash_search (qtexts_htab , & queryid , HASH_REMOVE , NULL );
712
+ return false;
713
+ }
714
+
694
715
strptr = (char * ) dsa_get_address (qtext_dsa , entry -> qtext_dp );
695
716
strlcpy (strptr , query_string , len );
717
+ return true;
696
718
}
697
719
698
720
void
@@ -705,7 +727,15 @@ aqo_qtexts_load(void)
705
727
Assert (qtext_dsa != NULL );
706
728
707
729
LWLockAcquire (& aqo_state -> qtexts_lock , LW_EXCLUSIVE );
708
- Assert (hash_get_num_entries (qtexts_htab ) == 0 );
730
+
731
+ if (hash_get_num_entries (qtexts_htab ) != 0 )
732
+ {
733
+ /* Someone have done it concurrently. */
734
+ elog (LOG , "[AQO] Another backend have loaded query texts concurrently." );
735
+ LWLockRelease (& aqo_state -> qtexts_lock );
736
+ return ;
737
+ }
738
+
709
739
data_load (PGAQO_TEXT_FILE , _deform_qtexts_record_cb , NULL );
710
740
711
741
/* Check existence of default feature space */
@@ -725,7 +755,7 @@ aqo_qtexts_load(void)
725
755
* Getting a data chunk from a caller, add a record into the 'ML data'
726
756
* shmem hash table. Allocate and fill DSA chunk for variadic part of the data.
727
757
*/
728
- static void
758
+ static bool
729
759
_deform_data_record_cb (void * data , size_t size )
730
760
{
731
761
bool found ;
@@ -737,7 +767,7 @@ _deform_data_record_cb(void *data, size_t size)
737
767
738
768
Assert (LWLockHeldByMeInMode (& aqo_state -> data_lock , LW_EXCLUSIVE ));
739
769
entry = (DataEntry * ) hash_search (data_htab , & fentry -> key ,
740
- HASH_ENTER , & found );
770
+ HASH_ENTER , & found );
741
771
Assert (!found );
742
772
743
773
/* Copy fixed-size part of entry byte-by-byte even with caves */
@@ -747,9 +777,20 @@ _deform_data_record_cb(void *data, size_t size)
747
777
sz = _compute_data_dsa (entry );
748
778
Assert (sz + offsetof(DataEntry , data_dp ) == size );
749
779
entry -> data_dp = dsa_allocate (data_dsa , sz );
750
- Assert (DsaPointerIsValid (entry -> data_dp ));
780
+
781
+ if (!_check_dsa_validity (entry -> data_dp ))
782
+ {
783
+ /*
784
+ * DSA stuck into problems. Rollback changes. Return false in belief
785
+ * that caller recognize it and don't try to call us more.
786
+ */
787
+ (void ) hash_search (data_htab , & fentry -> key , HASH_REMOVE , NULL );
788
+ return false;
789
+ }
790
+
751
791
dsa_ptr = (char * ) dsa_get_address (data_dsa , entry -> data_dp );
752
792
memcpy (dsa_ptr , ptr , sz );
793
+ return true;
753
794
}
754
795
755
796
void
@@ -759,14 +800,22 @@ aqo_data_load(void)
759
800
Assert (data_dsa != NULL );
760
801
761
802
LWLockAcquire (& aqo_state -> data_lock , LW_EXCLUSIVE );
762
- Assert (hash_get_num_entries (data_htab ) == 0 );
803
+
804
+ if (hash_get_num_entries (data_htab ) != 0 )
805
+ {
806
+ /* Someone have done it concurrently. */
807
+ elog (LOG , "[AQO] Another backend have loaded query data concurrently." );
808
+ LWLockRelease (& aqo_state -> data_lock );
809
+ return ;
810
+ }
811
+
763
812
data_load (PGAQO_DATA_FILE , _deform_data_record_cb , NULL );
764
813
765
814
aqo_state -> data_changed = false; /* mem data is consistent with disk */
766
815
LWLockRelease (& aqo_state -> data_lock );
767
816
}
768
817
769
- static void
818
+ static bool
770
819
_deform_queries_record_cb (void * data , size_t size )
771
820
{
772
821
bool found ;
@@ -780,20 +829,22 @@ _deform_queries_record_cb(void *data, size_t size)
780
829
entry = (QueriesEntry * ) hash_search (queries_htab , & queryid , HASH_ENTER , & found );
781
830
Assert (!found );
782
831
memcpy (entry , data , sizeof (QueriesEntry ));
832
+ return true;
783
833
}
784
834
785
835
void
786
836
aqo_queries_load (void )
787
837
{
788
- long entries ;
789
838
bool found ;
790
839
uint64 queryid = 0 ;
791
840
792
841
Assert (!LWLockHeldByMe (& aqo_state -> queries_lock ));
793
842
794
843
LWLockAcquire (& aqo_state -> queries_lock , LW_EXCLUSIVE );
795
- entries = hash_get_num_entries (queries_htab );
796
- Assert (entries == 0 );
844
+
845
+ /* Load on postmaster sturtup. So no any concurrent actions possible here. */
846
+ Assert (hash_get_num_entries (queries_htab ) == 0 );
847
+
797
848
data_load (PGAQO_QUERIES_FILE , _deform_queries_record_cb , NULL );
798
849
799
850
/* Check existence of default feature space */
@@ -836,14 +887,23 @@ data_load(const char *filename, deform_record_t callback, void *ctx)
836
887
{
837
888
void * data ;
838
889
size_t size ;
890
+ bool res ;
839
891
840
892
if (fread (& size , sizeof (size ), 1 , file ) != 1 )
841
893
goto read_error ;
842
894
data = palloc (size );
843
895
if (fread (data , size , 1 , file ) != 1 )
844
896
goto read_error ;
845
- callback (data , size );
897
+ res = callback (data , size );
846
898
pfree (data );
899
+
900
+ if (!res )
901
+ {
902
+ /* Error detected. Do not try to read tails of the storage. */
903
+ elog (LOG , "[AQO] Because of an error skip %ld storage records." ,
904
+ num - i );
905
+ break ;
906
+ }
847
907
}
848
908
849
909
FreeFile (file );
@@ -896,11 +956,15 @@ dsa_init()
896
956
Assert (aqo_state -> data_dsa_handler == DSM_HANDLE_INVALID );
897
957
898
958
qtext_dsa = dsa_create (aqo_state -> qtext_trancheid );
959
+ Assert (qtext_dsa != NULL );
960
+
961
+ if (dsm_size_max > 0 )
962
+ dsa_set_size_limit (qtext_dsa , dsm_size_max * 1024 * 1024 );
963
+
899
964
dsa_pin (qtext_dsa );
900
965
aqo_state -> qtexts_dsa_handler = dsa_get_handle (qtext_dsa );
901
966
902
- data_dsa = dsa_create (aqo_state -> data_trancheid );
903
- dsa_pin (data_dsa );
967
+ data_dsa = qtext_dsa ;
904
968
aqo_state -> data_dsa_handler = dsa_get_handle (data_dsa );
905
969
906
970
/* Load and initialize query texts hash table */
@@ -910,11 +974,10 @@ dsa_init()
910
974
else
911
975
{
912
976
qtext_dsa = dsa_attach (aqo_state -> qtexts_dsa_handler );
913
- data_dsa = dsa_attach ( aqo_state -> data_dsa_handler ) ;
977
+ data_dsa = qtext_dsa ;
914
978
}
915
979
916
980
dsa_pin_mapping (qtext_dsa );
917
- dsa_pin_mapping (data_dsa );
918
981
MemoryContextSwitchTo (old_context );
919
982
LWLockRelease (& aqo_state -> lock );
920
983
@@ -973,7 +1036,17 @@ aqo_qtext_store(uint64 queryid, const char *query_string)
973
1036
entry -> queryid = queryid ;
974
1037
size = size > querytext_max_size ? querytext_max_size : size ;
975
1038
entry -> qtext_dp = dsa_allocate (qtext_dsa , size );
976
- Assert (DsaPointerIsValid (entry -> qtext_dp ));
1039
+
1040
+ if (!_check_dsa_validity (entry -> qtext_dp ))
1041
+ {
1042
+ /*
1043
+ * DSA stuck into problems. Rollback changes. Return false in belief
1044
+ * that caller recognize it and don't try to call us more.
1045
+ */
1046
+ (void ) hash_search (qtexts_htab , & queryid , HASH_REMOVE , NULL );
1047
+ return false;
1048
+ }
1049
+
977
1050
strptr = (char * ) dsa_get_address (qtext_dsa , entry -> qtext_dp );
978
1051
strlcpy (strptr , query_string , size );
979
1052
aqo_state -> qtexts_changed = true;
@@ -1173,7 +1246,16 @@ aqo_data_store(uint64 fs, int fss, OkNNrdata *data, List *reloids)
1173
1246
1174
1247
size = _compute_data_dsa (entry );
1175
1248
entry -> data_dp = dsa_allocate0 (data_dsa , size );
1176
- Assert (DsaPointerIsValid (entry -> data_dp ));
1249
+
1250
+ if (!_check_dsa_validity (entry -> data_dp ))
1251
+ {
1252
+ /*
1253
+ * DSA stuck into problems. Rollback changes. Return false in belief
1254
+ * that caller recognize it and don't try to call us more.
1255
+ */
1256
+ (void ) hash_search (data_htab , & key , HASH_REMOVE , NULL );
1257
+ return false;
1258
+ }
1177
1259
}
1178
1260
1179
1261
Assert (DsaPointerIsValid (entry -> data_dp ));
@@ -1195,7 +1277,16 @@ aqo_data_store(uint64 fs, int fss, OkNNrdata *data, List *reloids)
1195
1277
/* Need to re-allocate DSA chunk */
1196
1278
dsa_free (data_dsa , entry -> data_dp );
1197
1279
entry -> data_dp = dsa_allocate0 (data_dsa , size );
1198
- Assert (DsaPointerIsValid (entry -> data_dp ));
1280
+
1281
+ if (!_check_dsa_validity (entry -> data_dp ))
1282
+ {
1283
+ /*
1284
+ * DSA stuck into problems. Rollback changes. Return false in belief
1285
+ * that caller recognize it and don't try to call us more.
1286
+ */
1287
+ (void ) hash_search (data_htab , & key , HASH_REMOVE , NULL );
1288
+ return false;
1289
+ }
1199
1290
}
1200
1291
ptr = (char * ) dsa_get_address (data_dsa , entry -> data_dp );
1201
1292
0 commit comments