PostgreSQL Source Code  git master
test_slru.c
Go to the documentation of this file.
1 /*--------------------------------------------------------------------------
2  *
3  * test_slru.c
4  * Test correctness of SLRU functions.
5  *
6  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/test/modules/test_slru/test_slru.c
11  *
12  * -------------------------------------------------------------------------
13  */
14 
15 #include "postgres.h"
16 
17 #include "access/slru.h"
18 #include "access/transam.h"
19 #include "miscadmin.h"
20 #include "storage/fd.h"
21 #include "storage/ipc.h"
22 #include "storage/shmem.h"
23 #include "utils/builtins.h"
24 
26 
27 /*
28  * SQL-callable entry points
29  */
39 
40 /* Number of SLRU page slots */
41 #define NUM_TEST_BUFFERS 16
42 
43 /* SLRU control lock */
45 #define TestSLRULock (&TestSLRULock)
46 
48 #define TestSlruCtl (&TestSlruCtlData)
49 
52 
53 static bool
54 test_slru_scan_cb(SlruCtl ctl, char *filename, int64 segpage, void *data)
55 {
56  elog(NOTICE, "Calling test_slru_scan_cb()");
57  return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
58 }
59 
60 Datum
62 {
63  int64 pageno = PG_GETARG_INT64(0);
65  int slotno;
66 
68 
69  slotno = SimpleLruZeroPage(TestSlruCtl, pageno);
70 
71  /* these should match */
72  Assert(TestSlruCtl->shared->page_number[slotno] == pageno);
73 
74  /* mark the page as dirty so as it would get written */
75  TestSlruCtl->shared->page_dirty[slotno] = true;
76  TestSlruCtl->shared->page_status[slotno] = SLRU_PAGE_VALID;
77 
78  /* write given data to the page, up to the limit of the page */
79  strncpy(TestSlruCtl->shared->page_buffer[slotno], data,
80  BLCKSZ - 1);
81 
84 
86 }
87 
88 Datum
90 {
93 }
94 
95 Datum
97 {
98  int64 pageno = PG_GETARG_INT64(0);
99  bool write_ok = PG_GETARG_BOOL(1);
100  char *data = NULL;
101  int slotno;
102 
103  /* find page in buffers, reading it if necessary */
105  slotno = SimpleLruReadPage(TestSlruCtl, pageno,
106  write_ok, InvalidTransactionId);
107  data = (char *) TestSlruCtl->shared->page_buffer[slotno];
109 
111 }
112 
113 Datum
115 {
116  int64 pageno = PG_GETARG_INT64(0);
117  char *data = NULL;
118  int slotno;
119 
120  /* find page in buffers, reading it if necessary */
122  pageno,
125  data = (char *) TestSlruCtl->shared->page_buffer[slotno];
127 
129 }
130 
131 Datum
133 {
134  int64 pageno = PG_GETARG_INT64(0);
135  bool found;
136 
140 
141  PG_RETURN_BOOL(found);
142 }
143 
144 Datum
146 {
147  int64 pageno = PG_GETARG_INT64(0);
148  FileTag ftag;
149  char path[MAXPGPATH];
150 
151  /* note that this flushes the full file a segment is located in */
152  ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
153  SlruSyncFileTag(TestSlruCtl, &ftag, path);
154 
155  elog(NOTICE, "Called SlruSyncFileTag() for segment %lld on path %s",
156  (long long) ftag.segno, path);
157 
158  PG_RETURN_VOID();
159 }
160 
161 Datum
163 {
164  int64 pageno = PG_GETARG_INT64(0);
165  FileTag ftag;
166 
167  ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
169 
170  elog(NOTICE, "Called SlruDeleteSegment() for segment %lld",
171  (long long) ftag.segno);
172 
173  PG_RETURN_VOID();
174 }
175 
176 Datum
178 {
179  int64 pageno = PG_GETARG_INT64(0);
180 
182  PG_RETURN_VOID();
183 }
184 
185 Datum
187 {
188  /* this calls SlruScanDirCbDeleteAll() internally, ensuring deletion */
190 
191  PG_RETURN_VOID();
192 }
193 
194 /*
195  * Module load callbacks and initialization.
196  */
197 
198 static void
200 {
203 
204  /* reserve shared memory for the test SLRU */
206 }
207 
208 static bool
209 test_slru_page_precedes_logically(int64 page1, int64 page2)
210 {
211  return page1 < page2;
212 }
213 
214 static void
216 {
217  /*
218  * Short segments names are well tested elsewhere so in this test we are
219  * focusing on long names.
220  */
221  const bool long_segment_names = true;
222  const char slru_dir_name[] = "pg_test_slru";
223  int test_tranche_id;
224 
227 
228  /*
229  * Create the SLRU directory if it does not exist yet, from the root of
230  * the data directory.
231  */
232  (void) MakePGDirectory(slru_dir_name);
233 
234  /* initialize the SLRU facility */
235  test_tranche_id = LWLockNewTrancheId();
236  LWLockRegisterTranche(test_tranche_id, "test_slru_tranche");
237  LWLockInitialize(TestSLRULock, test_tranche_id);
238 
240  SimpleLruInit(TestSlruCtl, "TestSLRU",
241  NUM_TEST_BUFFERS, 0, TestSLRULock, slru_dir_name,
242  test_tranche_id, SYNC_HANDLER_NONE, long_segment_names);
243 }
244 
245 void
246 _PG_init(void)
247 {
249  ereport(ERROR,
250  (errmsg("cannot load \"%s\" after startup", "test_slru"),
251  errdetail("\"%s\" must be loaded with shared_preload_libraries.",
252  "test_slru")));
253 
256 
259 }
int errdetail(const char *fmt,...)
Definition: elog.c:1202
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define ERROR
Definition: elog.h:39
#define NOTICE
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:149
int MakePGDirectory(const char *directoryName)
Definition: fd.c:3883
#define PG_RETURN_VOID()
Definition: fmgr.h:349
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:274
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
void(* shmem_startup_hook_type)(void)
Definition: ipc.h:22
shmem_startup_hook_type shmem_startup_hook
Definition: ipci.c:57
void RequestAddinShmemSpace(Size size)
Definition: ipci.c:73
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockHeldByMe(LWLock *lock)
Definition: lwlock.c:1920
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1195
void LWLockRegisterTranche(int tranche_id, const char *tranche_name)
Definition: lwlock.c:651
int LWLockNewTrancheId(void)
Definition: lwlock.c:627
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition: lwlock.c:730
@ LW_EXCLUSIVE
Definition: lwlock.h:116
void(* shmem_request_hook_type)(void)
Definition: miscadmin.h:503
shmem_request_hook_type shmem_request_hook
Definition: miscinit.c:1774
bool process_shared_preload_libraries_in_progress
Definition: miscinit.c:1771
#define MAXPGPATH
const void * data
static char * filename
Definition: pg_dumpall.c:121
uintptr_t Datum
Definition: postgres.h:64
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
Definition: slru.c:523
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:642
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1184
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition: slru.c:214
bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int64 pageno)
Definition: slru.c:654
void SlruDeleteSegment(SlruCtl ctl, int64 segno)
Definition: slru.c:1355
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1607
bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: slru.c:1560
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
Definition: slru.c:423
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1647
int SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
Definition: slru.c:308
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition: slru.c:1254
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:182
#define SLRU_PAGES_PER_SEGMENT
Definition: slru.h:34
@ SLRU_PAGE_VALID
Definition: slru.h:46
Definition: sync.h:51
uint64 segno
Definition: sync.h:55
Definition: lwlock.h:41
@ SYNC_HANDLER_NONE
Definition: sync.h:42
static void test_slru_shmem_startup(void)
Definition: test_slru.c:215
Datum test_slru_page_delete(PG_FUNCTION_ARGS)
Definition: test_slru.c:162
static bool test_slru_page_precedes_logically(int64 page1, int64 page2)
Definition: test_slru.c:209
Datum test_slru_page_write(PG_FUNCTION_ARGS)
Definition: test_slru.c:61
void _PG_init(void)
Definition: test_slru.c:246
Datum test_slru_page_exists(PG_FUNCTION_ARGS)
Definition: test_slru.c:132
Datum test_slru_page_writeall(PG_FUNCTION_ARGS)
Definition: test_slru.c:89
PG_MODULE_MAGIC
Definition: test_slru.c:25
Datum test_slru_page_readonly(PG_FUNCTION_ARGS)
Definition: test_slru.c:114
#define TestSLRULock
Definition: test_slru.c:45
Datum test_slru_page_truncate(PG_FUNCTION_ARGS)
Definition: test_slru.c:177
static shmem_startup_hook_type prev_shmem_startup_hook
Definition: test_slru.c:51
static shmem_request_hook_type prev_shmem_request_hook
Definition: test_slru.c:50
Datum test_slru_page_read(PG_FUNCTION_ARGS)
Definition: test_slru.c:96
#define NUM_TEST_BUFFERS
Definition: test_slru.c:41
Datum test_slru_delete_all(PG_FUNCTION_ARGS)
Definition: test_slru.c:186
static void test_slru_shmem_request(void)
Definition: test_slru.c:199
PG_FUNCTION_INFO_V1(test_slru_page_write)
static SlruCtlData TestSlruCtlData
Definition: test_slru.c:47
Datum test_slru_page_sync(PG_FUNCTION_ARGS)
Definition: test_slru.c:145
static bool test_slru_scan_cb(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: test_slru.c:54
#define TestSlruCtl
Definition: test_slru.c:48
#define InvalidTransactionId
Definition: transam.h:31
char * text_to_cstring(const text *t)
Definition: varlena.c:217
text * cstring_to_text(const char *s)
Definition: varlena.c:184