1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 
26 
27 #define DBACC_C
28 #include "Dbacc.hpp"
29 
30 #define JAM_FILE_ID 346
31 
32 
33 #define DEBUG(x) { ndbout << "ACC::" << x << endl; }
34 
initData()35 void Dbacc::initData()
36 {
37   coprecsize = ZOPRECSIZE;
38   cpagesize = ZPAGESIZE;
39   ctablesize = ZTABLESIZE;
40   cfragmentsize = ZFRAGMENTSIZE;
41   cscanRecSize = ZSCAN_REC_SIZE;
42 
43   Pool_context pc;
44   pc.m_block = this;
45   directoryPool.init(RT_DBACC_DIRECTORY, pc);
46 
47   fragmentrec = 0;
48   operationrec = 0;
49   page8 = 0;
50   scanRec = 0;
51   tabrec = 0;
52 
53   m_free_pct = 0;
54   m_oom = false;
55   cnoOfAllocatedPagesMax = cnoOfAllocatedPages = cpagesize = cpageCount = m_maxAllocPages = 0;
56   // Records with constant sizes
57 
58   RSS_OP_COUNTER_INIT(cnoOfFreeFragrec);
59 
60 }//Dbacc::initData()
61 
initRecords()62 void Dbacc::initRecords()
63 {
64   {
65     AllocChunk chunks[16];
66     const Uint32 pages = (cpagesize + 3) / 4;
67     const Uint32 chunkcnt = allocChunks(chunks, 16, RT_DBTUP_PAGE, pages,
68                                         CFG_DB_INDEX_MEM);
69 
70     /**
71      * Set base ptr
72      */
73     Ptr<GlobalPage> pagePtr;
74     m_shared_page_pool.getPtr(pagePtr, chunks[0].ptrI);
75     page8 = (Page8*)pagePtr.p;
76 
77     /**
78      * 1) Build free-list per chunk
79      * 2) Add chunks to cfreepages-list
80      */
81     cfreepages.init();
82     cpagesize = 0;
83     cpageCount = 0;
84     LocalPage8List freelist(*this, cfreepages);
85     for (Int32 i = chunkcnt - 1; i >= 0; i--)
86     {
87       Ptr<GlobalPage> pagePtr;
88       m_shared_page_pool.getPtr(pagePtr, chunks[i].ptrI);
89       const Uint32 cnt = 4 * chunks[i].cnt; // 4 8k per 32k
90       Page8* base = (Page8*)pagePtr.p;
91       ndbrequire(base >= page8);
92       const Uint32 ptrI = Uint32(base - page8);
93       if (ptrI + cnt > cpagesize)
94         cpagesize = ptrI + cnt;
95       for (Uint32 j = 0; j < cnt; j++)
96       {
97         refresh_watch_dog();
98         freelist.addFirst(Page8Ptr::get(&base[j], ptrI + j));
99       }
100 
101       cpageCount += cnt;
102       ndbassert(freelist.count() + cnoOfAllocatedPages == cpageCount);
103     }
104     m_maxAllocPages = cpagesize;
105   }
106 
107   operationrec = (Operationrec*)allocRecord("Operationrec",
108 					    sizeof(Operationrec),
109 					    coprecsize);
110 
111   fragmentrec = (Fragmentrec*)allocRecord("Fragmentrec",
112 					  sizeof(Fragmentrec),
113 					  cfragmentsize);
114 
115   scanRec = (ScanRec*)allocRecord("ScanRec",
116 				  sizeof(ScanRec),
117 				  cscanRecSize);
118 
119   tabrec = (Tabrec*)allocRecord("Tabrec",
120 				sizeof(Tabrec),
121 				ctablesize);
122 }//Dbacc::initRecords()
123 
Dbacc(Block_context & ctx,Uint32 instanceNumber)124 Dbacc::Dbacc(Block_context& ctx, Uint32 instanceNumber):
125   SimulatedBlock(DBACC, ctx, instanceNumber),
126   c_tup(0)
127 {
128   BLOCK_CONSTRUCTOR(Dbacc);
129 
130   // Transit signals
131   addRecSignal(GSN_DUMP_STATE_ORD, &Dbacc::execDUMP_STATE_ORD);
132   addRecSignal(GSN_DEBUG_SIG, &Dbacc::execDEBUG_SIG);
133   addRecSignal(GSN_CONTINUEB, &Dbacc::execCONTINUEB);
134   addRecSignal(GSN_ACC_CHECK_SCAN, &Dbacc::execACC_CHECK_SCAN);
135   addRecSignal(GSN_EXPANDCHECK2, &Dbacc::execEXPANDCHECK2);
136   addRecSignal(GSN_SHRINKCHECK2, &Dbacc::execSHRINKCHECK2);
137   addRecSignal(GSN_READ_PSEUDO_REQ, &Dbacc::execREAD_PSEUDO_REQ);
138 
139   // Received signals
140   addRecSignal(GSN_STTOR, &Dbacc::execSTTOR);
141   addRecSignal(GSN_ACCKEYREQ, &Dbacc::execACCKEYREQ);
142   addRecSignal(GSN_ACCSEIZEREQ, &Dbacc::execACCSEIZEREQ);
143   addRecSignal(GSN_ACCFRAGREQ, &Dbacc::execACCFRAGREQ);
144   addRecSignal(GSN_NEXT_SCANREQ, &Dbacc::execNEXT_SCANREQ);
145   addRecSignal(GSN_ACC_ABORTREQ, &Dbacc::execACC_ABORTREQ);
146   addRecSignal(GSN_ACC_SCANREQ, &Dbacc::execACC_SCANREQ);
147   addRecSignal(GSN_ACCMINUPDATE, &Dbacc::execACCMINUPDATE);
148   addRecSignal(GSN_ACC_COMMITREQ, &Dbacc::execACC_COMMITREQ);
149   addRecSignal(GSN_ACC_TO_REQ, &Dbacc::execACC_TO_REQ);
150   addRecSignal(GSN_ACC_LOCKREQ, &Dbacc::execACC_LOCKREQ);
151   addRecSignal(GSN_NDB_STTOR, &Dbacc::execNDB_STTOR);
152   addRecSignal(GSN_DROP_TAB_REQ, &Dbacc::execDROP_TAB_REQ);
153   addRecSignal(GSN_READ_CONFIG_REQ, &Dbacc::execREAD_CONFIG_REQ, true);
154   addRecSignal(GSN_DROP_FRAG_REQ, &Dbacc::execDROP_FRAG_REQ);
155 
156   addRecSignal(GSN_DBINFO_SCANREQ, &Dbacc::execDBINFO_SCANREQ);
157   addRecSignal(GSN_NODE_STATE_REP, &Dbacc::execNODE_STATE_REP, true);
158 
159   initData();
160 
161 #ifdef VM_TRACE
162   {
163     void* tmp[] = { &fragrecptr,
164                     &operationRecPtr,
165                     &idrOperationRecPtr,
166                     &mlpqOperPtr,
167                     &queOperPtr,
168                     &readWriteOpPtr,
169                     &ancPageptr,
170                     &colPageptr,
171                     &ccoPageptr,
172                     &datapageptr,
173                     &delPageptr,
174                     &excPageptr,
175                     &expPageptr,
176                     &gdiPageptr,
177                     &gePageptr,
178                     &gflPageptr,
179                     &idrPageptr,
180                     &ilcPageptr,
181                     &inpPageptr,
182                     &iopPageptr,
183                     &lastPageptr,
184                     &lastPrevpageptr,
185                     &lcnPageptr,
186                     &lcnCopyPageptr,
187                     &lupPageptr,
188                     &ciPageidptr,
189                     &gsePageidptr,
190                     &isoPageptr,
191                     &nciPageidptr,
192                     &rsbPageidptr,
193                     &rscPageidptr,
194                     &slPageidptr,
195                     &sscPageidptr,
196                     &rlPageptr,
197                     &rlpPageptr,
198                     &ropPageptr,
199                     &rpPageptr,
200                     &slPageptr,
201                     &spPageptr,
202                     &scanPtr,
203                     &tabptr
204     };
205     init_globals_list(tmp, sizeof(tmp)/sizeof(tmp[0]));
206   }
207 #endif
208 }//Dbacc::Dbacc()
209 
~Dbacc()210 Dbacc::~Dbacc()
211 {
212   deallocRecord((void **)&fragmentrec, "Fragmentrec",
213 		sizeof(Fragmentrec),
214 		cfragmentsize);
215 
216   deallocRecord((void **)&operationrec, "Operationrec",
217 		sizeof(Operationrec),
218 		coprecsize);
219 
220   deallocRecord((void **)&scanRec, "ScanRec",
221 		sizeof(ScanRec),
222 		cscanRecSize);
223 
224   deallocRecord((void **)&tabrec, "Tabrec",
225 		sizeof(Tabrec),
226 		ctablesize);
227   }//Dbacc::~Dbacc()
228 
229 BLOCK_FUNCTIONS(Dbacc)
230