1
00:00:00,060 --> 00:00:02,600
Michael: Hello and welcome to PostgresFM, a weekly show about
2
00:00:02,600 --> 00:00:03,540
all things PostgreSQL.
3
00:00:03,740 --> 00:00:05,580
I am Michael, founder of pgMustard.
4
00:00:05,680 --> 00:00:07,640
This is Nikolay, founder of Postgres.AI.
5
00:00:07,640 --> 00:00:08,460
Hello Nikolay.
6
00:00:08,940 --> 00:00:10,300
Nikolay: Hi Michael, how are you?
7
00:00:10,860 --> 00:00:12,280
Michael: I'm good, how are you?
8
00:00:12,560 --> 00:00:13,280
Nikolay: Very good.
9
00:00:13,580 --> 00:00:15,660
Let's talk about some crazy stuff.
10
00:00:16,160 --> 00:00:20,040
Michael: I chose the topic this week and it was a listener suggestion,
11
00:00:20,280 --> 00:00:24,020
it's Postgres gotchas and we've had a short discussion before
12
00:00:24,020 --> 00:00:26,700
this call about what we should even count as gotchas.
13
00:00:27,400 --> 00:00:30,620
So how do you define it, what do you think of when you hear Postgres
14
00:00:30,620 --> 00:00:31,120
gotcha?
15
00:00:31,580 --> 00:00:35,160
Nikolay: Well if you for example run, I don't know, like SELECT
16
00:00:35,360 --> 00:00:39,980
5/2, what will you get?
17
00:00:41,580 --> 00:00:43,220
Michael: Is this like data type casting?
18
00:00:43,740 --> 00:00:47,000
Nikolay: Right right well it's not Postgres related I think it's
19
00:00:47,040 --> 00:00:51,140
SQL related but still what do you expect to get?
20
00:00:51,180 --> 00:00:54,560
Normal person would expect 2.5, right?
21
00:00:55,260 --> 00:00:58,300
But you will get, and I just double checked because I always...
22
00:00:59,220 --> 00:01:02,260
I'm always like thinking, am I right?
23
00:01:02,580 --> 00:01:05,580
So you're getting 2, so 5.
24
00:01:05,940 --> 00:01:08,740
Michael: 0 wow, I actually thought it was going to be 3.
25
00:01:13,700 --> 00:01:15,700
Nikolay: We probably have 2 things to discuss here.
26
00:01:15,700 --> 00:01:19,560
First is of course integer and integer, right?
27
00:01:19,560 --> 00:01:23,000
Results should be integer, so there's no decimal, there's no
28
00:01:23,000 --> 00:01:24,820
point here, there's no dot.
29
00:01:25,280 --> 00:01:27,680
And, but 2 or 3?
30
00:01:29,340 --> 00:01:31,600
Rounding or flooring, right?
31
00:01:31,640 --> 00:01:35,280
Michael: Yeah, because like rounding conventions at least where
32
00:01:35,280 --> 00:01:40,600
I grew up we generally round up from 0.5 but not clearly not
33
00:01:40,600 --> 00:01:45,560
here anyway I like this almost this definition which is something
34
00:01:45,860 --> 00:01:50,820
where you may expect 1 outcome but a different outcome happens.
35
00:01:50,860 --> 00:01:51,360
That's
36
00:01:51,560 --> 00:01:54,100
Nikolay: unexpected behavior basically in other words.
37
00:01:54,860 --> 00:01:57,900
Michael: Yeah, especially unexpected if you haven't read the
38
00:01:57,900 --> 00:01:58,400
documentation.
39
00:02:00,640 --> 00:02:04,740
Nikolay: Sometimes documentation also wrong or misleading or
40
00:02:05,020 --> 00:02:07,360
sometimes it's just confusing.
41
00:02:08,540 --> 00:02:09,220
Michael: Yeah fair enough.
42
00:02:09,220 --> 00:02:12,160
I just wanted an excuse to list a few things that are made very
43
00:02:12,160 --> 00:02:16,020
clear in the documentation, but I know people get confused by
44
00:02:16,020 --> 00:02:17,940
it because often they don't read that.
45
00:02:18,820 --> 00:02:22,280
Nikolay: You know, I'm curious, I actually found a good example,
46
00:02:22,280 --> 00:02:22,540
right?
47
00:02:22,540 --> 00:02:25,680
It's like probably a gotcha SQL, not Postgres, because
48
00:02:25,680 --> 00:02:30,040
I think it's maybe defined by standard, but, and this is super
49
00:02:30,040 --> 00:02:34,940
basic, but I'm wondering why indeed it's 2 not 3 because if you
50
00:02:34,940 --> 00:02:39,440
for example I what I did I double check of course I checked floor
51
00:02:39,480 --> 00:02:44,060
and round functions and of course
as expected floor I converted
52
00:02:44,060 --> 00:02:47,780
5 to numeric or just just to
53
00:02:47,780 --> 00:02:49,320
Michael: last with the colon colon
54
00:02:49,360 --> 00:02:52,360
Nikolay: you're right right so
the result is also numeric and
55
00:02:52,360 --> 00:02:59,480
then we have of course 2.500 like
so but then I checked floor
56
00:02:59,480 --> 00:03:03,800
gives me 2 round gives me 3 is
expected because 2.5 means like
57
00:03:03,800 --> 00:03:08,800
we need if you're rounding according
to their names for these
58
00:03:08,800 --> 00:03:09,860
rules, I don't remember, right?
59
00:03:09,860 --> 00:03:14,700
But usually 5 you go up, 4 you
go down, right?
60
00:03:15,540 --> 00:03:18,660
And it gives 3, Round gives 3.
61
00:03:18,660 --> 00:03:26,100
But I was thinking, okay, why 5
slash 2 integer and integer gives
62
00:03:26,100 --> 00:03:27,320
2 and not 3?
63
00:03:27,400 --> 00:03:29,200
Maybe because it uses 4.
64
00:03:30,180 --> 00:03:34,120
We could check the source code,
of course, but the next thing
65
00:03:34,120 --> 00:03:36,300
I checked is the final thing I
checked.
66
00:03:36,740 --> 00:03:40,160
5 converted to numeric slash 2
gives you 2.5.
67
00:03:40,260 --> 00:03:42,040
And then you convert back to int,
right?
68
00:03:42,040 --> 00:03:43,860
Again, double colon int.
69
00:03:44,380 --> 00:03:45,600
It gives 3.
70
00:03:46,300 --> 00:03:46,800
Amazing.
71
00:03:50,440 --> 00:03:55,940
So how come we have 2 if we don't
use type conversion, explicit
72
00:03:55,960 --> 00:03:57,320
type conversion at all?
73
00:03:58,080 --> 00:03:58,760
Any ideas?
74
00:03:59,760 --> 00:04:01,580
It was good gotcha to find.
75
00:04:01,960 --> 00:04:04,200
I always knew that it's 2 because
I demonstrated.
76
00:04:04,200 --> 00:04:06,920
I just didn't think like why.
77
00:04:07,500 --> 00:04:08,600
Now I think why.
78
00:04:08,940 --> 00:04:09,940
I have questions.
79
00:04:10,240 --> 00:04:13,780
Maybe there is some good explanation,
simple, but I can see easily
80
00:04:13,780 --> 00:04:15,040
that it can be gotcha.
81
00:04:15,480 --> 00:04:17,180
It can be considered gotcha.
82
00:04:17,860 --> 00:04:20,420
And let's agree on 1 more thing.
83
00:04:20,740 --> 00:04:22,400
We don't talk about nulls today.
84
00:04:23,920 --> 00:04:26,520
Michael: I actually did have them
on my list, but not to go into
85
00:04:26,520 --> 00:04:27,020
detail.
86
00:04:27,260 --> 00:04:30,580
Nikolay: We had a whole episode,
and this whole episode is telling
87
00:04:30,580 --> 00:04:36,000
like, nulls are surrounded by gotchas
both like standard defined
88
00:04:36,600 --> 00:04:41,040
standard produce and like global
SQL gotchas and local Postgres
89
00:04:41,040 --> 00:04:45,060
related gotchas as well for example
when you go to a race right
90
00:04:45,060 --> 00:04:49,460
Let's just exclude it because it's
a whole massive area.
91
00:04:49,900 --> 00:04:51,260
Michael: I think that's very sensible.
92
00:04:51,600 --> 00:04:53,800
And if you haven't listened to
that episode, I'll link it up
93
00:04:53,800 --> 00:04:54,740
in the show notes.
94
00:04:55,240 --> 00:04:58,940
Nikolay: Consider it to be fully
included here.
95
00:04:59,140 --> 00:04:59,640
Yeah.
96
00:05:00,080 --> 00:05:00,580
Right.
97
00:05:00,920 --> 00:05:03,680
Okay, let's maybe switch to your
ideas.
98
00:05:03,680 --> 00:05:06,400
I know you have a list, pull something
from it.
99
00:05:06,460 --> 00:05:09,940
Michael: Yeah, I've got a few that
I wanted to make sure we mentioned.
100
00:05:10,080 --> 00:05:14,180
I'm gonna start with some ones
I consider more beginner level
101
00:05:14,540 --> 00:05:17,580
gotchas and then maybe we can work
our way up a little bit.
102
00:05:17,620 --> 00:05:23,880
The first 1 I had is 1 I see all
the time in kind of forums every
103
00:05:23,880 --> 00:05:28,260
now and again on Reddit, quite
a few times in like the Postgres
104
00:05:28,260 --> 00:05:30,520
Slack, a few up on a few mailing
lists.
105
00:05:31,220 --> 00:05:35,760
People getting confused or annoyed
when they name objects in
106
00:05:35,760 --> 00:05:42,380
Postgres and they use mixed case,
so maybe camel case or some
107
00:05:42,380 --> 00:05:47,220
way of naming a table like for
example like a two-worded name
108
00:05:47,380 --> 00:05:50,640
and using capital letters for the
2 names and no space in between
109
00:05:50,640 --> 00:05:53,680
them that kind of thing and then
realizing the table is not called
110
00:05:53,680 --> 00:05:58,040
that behind the scenes and it's
all lowercase and if they've
111
00:05:58,120 --> 00:06:02,820
used an ORM or something to name
these at the ORM often puts
112
00:06:03,420 --> 00:06:07,500
quotes around those case names
so then they become cased in the
113
00:06:07,500 --> 00:06:08,000
database.
114
00:06:08,420 --> 00:06:13,300
So I think this whole area is like
a 1 big gotcha for beginners
115
00:06:14,440 --> 00:06:18,060
and the people who set up the schema
in the first place, if they
116
00:06:18,340 --> 00:06:22,340
do something like this, if they
don't just use lowercase object
117
00:06:22,340 --> 00:06:26,140
names, can really make life a bit
painful for everybody that
118
00:06:26,140 --> 00:06:29,680
comes after them having to double
quote everything.
119
00:06:30,180 --> 00:06:33,840
Nikolay: Yeah, especially Java
people like it.
120
00:06:34,300 --> 00:06:35,040
Michael: Oh, really?
121
00:06:35,140 --> 00:06:37,180
Nikolay: Yeah, I noticed.
122
00:06:37,940 --> 00:06:43,180
Usually, if we have a new customer
and we start discussing their
123
00:06:43,180 --> 00:06:47,780
database, we see some camel-stack-cased
table names.
124
00:06:47,780 --> 00:06:52,440
And I think, I'm already thinking,
are you Java guys?
125
00:06:52,440 --> 00:06:53,540
Yeah, there are.
126
00:06:53,940 --> 00:06:56,260
Usually, not always, but usually
so.
127
00:06:56,440 --> 00:07:00,520
And my previous startup was using
it camel-style.
128
00:07:03,420 --> 00:07:06,240
And we just decided to keep it
as is because it was inherited
129
00:07:06,260 --> 00:07:06,960
from some...
130
00:07:07,200 --> 00:07:09,260
I think it was in MySQL originally.
131
00:07:09,900 --> 00:07:14,020
Like, we started very lean, so
we borrowed some schema from some
132
00:07:14,020 --> 00:07:15,080
open source project.
133
00:07:15,480 --> 00:07:16,580
And it had it.
134
00:07:16,640 --> 00:07:20,680
And I just, knowing this very well,
I still decided to keep it.
135
00:07:20,680 --> 00:07:22,960
But the problem with double quotes
is not like...
136
00:07:22,960 --> 00:07:24,640
It's not a big deal, but when...
137
00:07:24,720 --> 00:07:27,760
You know what comes with quotes
usually, right?
138
00:07:28,580 --> 00:07:29,080
Backslashes.
139
00:07:30,480 --> 00:07:31,180
Michael: Oh, having...
140
00:07:31,180 --> 00:07:32,800
Yeah, having to escape them.
141
00:07:32,900 --> 00:07:34,920
Nikolay: Yeah, and you cannot escape
from this.
142
00:07:34,920 --> 00:07:37,400
You need to use it to escape.
143
00:07:37,660 --> 00:07:37,940
Right?
144
00:07:37,940 --> 00:07:39,980
I mean, yeah.
145
00:07:40,080 --> 00:07:44,780
And backslashes, if you have automation
in many languages, like
146
00:07:44,780 --> 00:07:46,100
sometimes it's nightmare.
147
00:07:46,960 --> 00:07:50,580
Right now we have an ongoing problem
with backslashes and escaping
148
00:07:51,040 --> 00:07:54,360
of quotes and double quotes in
our AI system.
149
00:07:54,440 --> 00:07:57,900
It's a combination of Python and
Bash actually.
150
00:07:58,520 --> 00:08:00,520
And yeah, it drives us crazy sometimes.
151
00:08:00,700 --> 00:08:03,220
We solved some problems, but not
all of them still.
152
00:08:03,580 --> 00:08:07,660
And when Yi needs to talk about
your table names and you give
153
00:08:07,660 --> 00:08:11,420
the schema with double quotes,
and then you want to experiment
154
00:08:11,480 --> 00:08:16,620
in DBLab to find some plans or
something, it sometimes is broken
155
00:08:16,620 --> 00:08:21,160
just because of problems with backslashes
and passing these pieces
156
00:08:21,220 --> 00:08:22,700
between different components.
157
00:08:24,060 --> 00:08:27,040
I would prefer keeping everything
lowercase, that's it.
158
00:08:27,040 --> 00:08:27,680
In post-process.
159
00:08:27,800 --> 00:08:28,300
Right?
160
00:08:29,440 --> 00:08:30,600
Snake style, right?
161
00:08:31,100 --> 00:08:31,600
Michael: Yeah.
162
00:08:31,620 --> 00:08:32,220
Nikolay: And that's it.
163
00:08:32,220 --> 00:08:33,640
And just forget about it.
164
00:08:35,220 --> 00:08:36,000
Michael: Yeah, plays.
165
00:08:36,140 --> 00:08:37,040
Pay for plays.
166
00:08:37,500 --> 00:08:40,440
Nikolay: I wanted to mention the
list of gotchas I saw actually
167
00:08:40,440 --> 00:08:44,960
this is like as we discussed right
before this recording I didn't
168
00:08:44,960 --> 00:08:49,780
know this the word gotcha until
2006 or 2007 and this is exactly
169
00:08:49,780 --> 00:08:52,860
when this list was published.
170
00:08:53,220 --> 00:08:56,500
And I remember we had 2 lists,
1 for Postgres and 1 for MySQL.
171
00:08:57,180 --> 00:09:00,840
For MySQL, it's outside of scope,
right?
172
00:09:01,100 --> 00:09:03,640
Again, even more than nulls.
173
00:09:03,820 --> 00:09:08,080
But this list, I'm looking at it
right now and I'm very first
174
00:09:08,080 --> 00:09:15,940
of all it's survived how many years
like it's insane 18 17 years.
175
00:09:16,860 --> 00:09:17,300
Wow.
176
00:09:17,300 --> 00:09:21,600
And I'm looking at this, it's quite
short list at SQLinfo.de,
177
00:09:23,100 --> 00:09:23,600
right?
178
00:09:24,480 --> 00:09:27,040
And almost everything is crossed
out.
179
00:09:27,980 --> 00:09:28,480
Good.
180
00:09:29,240 --> 00:09:31,640
Michael: Yeah, this I've never
seen this page before.
181
00:09:31,640 --> 00:09:32,740
This is really cool.
182
00:09:32,980 --> 00:09:36,980
And yeah, maybe more than half
of them have been cost
183
00:09:36,980 --> 00:09:37,480
down.
184
00:09:40,080 --> 00:09:41,760
Nikolay: Yeah, account start is very slow.
185
00:09:42,660 --> 00:09:44,120
Let's just laugh at it.
186
00:09:45,060 --> 00:09:47,140
Michael: Oh, and we had an episode
on that, right?
187
00:09:47,540 --> 00:09:48,840
Nikolay: I think we should.
188
00:09:48,840 --> 00:09:51,580
Unicode means UTF-8 left as well.
189
00:09:51,580 --> 00:09:52,400
Well, yeah.
190
00:09:53,740 --> 00:09:56,840
Yeah, constraint checking is interesting,
but maybe let's not
191
00:09:56,840 --> 00:09:57,620
dive into it.
192
00:09:57,620 --> 00:10:00,720
And finally, I wanted to highlight
what else is left.
193
00:10:00,720 --> 00:10:01,660
Only 4 items.
194
00:10:01,880 --> 00:10:02,880
5, Okay, 5.
195
00:10:02,880 --> 00:10:06,960
But 1 of them is upgrades, upgrades,
related stuff.
196
00:10:07,200 --> 00:10:12,100
And I was discussing on Twitter,
on X, I was discussing this
197
00:10:12,100 --> 00:10:13,940
topic over the last few days.
198
00:10:14,180 --> 00:10:20,260
I just checked documentation of
3 major managed Postgres providers.
199
00:10:20,840 --> 00:10:24,300
So RDS, Cloud SQL, and Azure Postgres.
200
00:10:25,240 --> 00:10:30,460
I saw that all of them say, okay,
upgrade is done, major upgrade.
201
00:10:30,600 --> 00:10:33,900
Now it's time, don't forget, now it's time to run ANALYZE.
202
00:10:33,900 --> 00:10:38,300
And they say ANALYZE like they give you a snippet, ANALYZE semicolon,
203
00:10:38,400 --> 00:10:41,220
which means it's single-threaded as well.
204
00:10:41,520 --> 00:10:43,860
First of all, they don't include it.
205
00:10:43,860 --> 00:10:46,800
None of them include it into automation.
206
00:10:47,620 --> 00:10:50,460
But we don't talk about managed Postgres providers today, we
207
00:10:50,460 --> 00:10:51,320
talk about Postgres.
208
00:10:52,500 --> 00:10:58,180
My question is why pg_upgrade does not include...
209
00:10:58,180 --> 00:11:01,220
It prints only some text in there, but who reads the text?
210
00:11:01,440 --> 00:11:05,140
Many people will say, for those who don't read, it's on their
211
00:11:05,140 --> 00:11:06,520
shoulders, it's their problem.
212
00:11:06,820 --> 00:11:08,460
But I cannot agree with it.
213
00:11:09,600 --> 00:11:14,340
Michael: I could even make a case for the gotcha here is that
214
00:11:14,340 --> 00:11:17,460
statistics are not preserved on major upgrade.
215
00:11:17,800 --> 00:11:23,860
I think if you asked somebody that didn't know whether they would
216
00:11:23,860 --> 00:11:27,900
expect the statistics to be wiped or to be preserved, somebody
217
00:11:27,900 --> 00:11:31,080
maybe doesn't understand how difficult it might be or like the
218
00:11:31,080 --> 00:11:34,640
catalog, like the reasons why they're not preserved, you'd be
219
00:11:34,640 --> 00:11:38,600
forgiven to think like in a in the most advanced open source
220
00:11:38,600 --> 00:11:42,600
database that that might be that might happen even though it's
221
00:11:42,600 --> 00:11:45,110
complicated and I think there has been some work.
222
00:11:45,110 --> 00:11:45,290
It should
223
00:11:45,290 --> 00:11:47,660
Nikolay: happen and Everyone agrees on it, just not solved.
224
00:11:48,280 --> 00:11:50,520
Michael: Yeah, so I think that's the main gotcha.
225
00:11:50,540 --> 00:11:54,280
And then, obviously, the solution at the moment is we need to
226
00:11:54,280 --> 00:11:55,060
want to analyze.
227
00:11:55,520 --> 00:11:56,980
Nikolay: Yeah, let's unwrap a little bit.
228
00:11:56,980 --> 00:11:59,860
So we talk about statistics, which is required for a planner
229
00:11:59,860 --> 00:12:01,720
to make right decisions.
230
00:12:02,300 --> 00:12:05,640
If the database is not trivial, like containing like 100 rows
231
00:12:05,640 --> 00:12:06,960
in each table, that's it.
232
00:12:06,960 --> 00:12:08,860
If it's not trivial, we need statistics.
233
00:12:09,520 --> 00:12:11,440
Without statistics, database is slow.
234
00:12:12,700 --> 00:12:17,680
And what happens, I think in a zillion cases, it happens.
235
00:12:17,920 --> 00:12:21,420
Like It's hard to estimate, but when I posted this tweet, I received
236
00:12:21,420 --> 00:12:29,120
several replies immediately that, oh, we got beaten by this badly.
237
00:12:31,400 --> 00:12:35,740
Some person wrote, we learned this hard way, obviously.
238
00:12:36,260 --> 00:12:38,460
And this is like what happens all the time.
239
00:12:38,460 --> 00:12:45,800
And recently, during summer, we also like failed to help a customer
240
00:12:45,800 --> 00:12:46,160
with it.
241
00:12:46,160 --> 00:12:48,580
Like we discussed major upgrades, but we...
242
00:12:48,680 --> 00:12:52,040
From now on, I'm pointing out, like, don't forget, don't forget,
243
00:12:52,040 --> 00:12:52,780
don't forget.
244
00:12:53,100 --> 00:12:55,960
But we discussed upgrades, we discussed some, like, complicated
245
00:12:56,040 --> 00:13:00,520
stuff, and then they went to upgrade, and next Monday they say,
246
00:13:00,520 --> 00:13:02,160
oh, today they are in Europe.
247
00:13:02,160 --> 00:13:06,220
So in the morning, it was already by the evening in Europe.
248
00:13:06,220 --> 00:13:10,380
And they say, we had nasty database incidents today because guess
249
00:13:10,380 --> 00:13:10,760
what?
250
00:13:10,760 --> 00:13:13,120
We forgot to run ANALYZE.
251
00:13:14,240 --> 00:13:18,480
And this is huge gotcha not only
by managed services, they could
252
00:13:18,480 --> 00:13:21,520
do it but I don't care too much
about them.
253
00:13:21,660 --> 00:13:23,040
This is a gotcha of pg_upgrade.
254
00:13:23,240 --> 00:13:26,140
I think it's very well understood,
there is work in progress
255
00:13:26,200 --> 00:13:31,980
for export and import of statistics,
like quite a long thread
256
00:13:31,980 --> 00:13:34,500
in hackers already and commitfest
entry.
257
00:13:34,900 --> 00:13:38,340
It's still not done, but there
is hope.
258
00:13:39,960 --> 00:13:41,400
There is 1 more thing here.
259
00:13:41,400 --> 00:13:44,940
So I think pg_upgrade definitely
should have it.
260
00:13:45,060 --> 00:13:48,220
And also pg_restore, but let's return
to it in a few minutes.
261
00:13:50,280 --> 00:13:54,780
So when someone says you need to
recalculate statistics yourself
262
00:13:55,240 --> 00:13:57,140
after upgrade, pg_upgrade.
263
00:13:58,920 --> 00:14:01,820
I definitely would expect pg_upgrade
to do this for sure.
264
00:14:02,020 --> 00:14:04,220
But okay, it just prints do it.
265
00:14:04,340 --> 00:14:07,420
pg_upgrade prints vacuumdb, I think,
no?
266
00:14:07,420 --> 00:14:10,280
Or in stages, or like vacuumdb
in stages.
267
00:14:10,280 --> 00:14:14,060
It has this vacuumdb analyze only
in stages.
268
00:14:14,060 --> 00:14:14,640
2 options.
269
00:14:14,640 --> 00:14:16,940
Analyze only means no vacuum and
just Analyze.
270
00:14:17,320 --> 00:14:23,420
In stages means first it gets only
1 bucket for each table, for
271
00:14:23,420 --> 00:14:25,320
each column actually, right?
272
00:14:25,520 --> 00:14:29,480
And then some midway until your...
273
00:14:29,480 --> 00:14:34,600
And then default_statistics_target
or individual column based
274
00:14:34,600 --> 00:14:36,180
setting for each column.
275
00:14:36,340 --> 00:14:39,780
default_statistics_target by default
is 100, 100 buckets.
276
00:14:40,560 --> 00:14:46,580
This is what defines how much Postgres
planner will know about
277
00:14:46,680 --> 00:14:48,780
distribution in each column, right?
278
00:14:48,780 --> 00:14:52,040
And it can be adjusted globally
or for individual columns.
279
00:14:52,840 --> 00:14:53,260
But...
280
00:14:53,260 --> 00:14:56,100
Michael: Almost like a sample size,
like the sample size increases
281
00:14:56,260 --> 00:14:57,320
of what it samples.
282
00:14:57,320 --> 00:14:57,560
Nikolay: Yeah.
283
00:14:57,560 --> 00:15:01,200
And I quickly realized this is
not what you want to do in OLTP,
284
00:15:01,220 --> 00:15:06,560
because in OLTP, you either include
Analyze inside maintenance
285
00:15:06,580 --> 00:15:06,980
window.
286
00:15:06,980 --> 00:15:11,180
In this case, there is no sense
to run it 3 times, or you just...
287
00:15:12,880 --> 00:15:14,940
Or that's it, there is only option
actually.
288
00:15:15,180 --> 00:15:19,440
Like, I don't trust in opening
gates with weak statistics.
289
00:15:19,680 --> 00:15:22,220
It will be like unpredictable again
incident.
290
00:15:23,080 --> 00:15:23,580
Michael: Yeah.
291
00:15:24,140 --> 00:15:24,820
Yeah, risky.
292
00:15:24,860 --> 00:15:28,080
But this feels like a topic that
might be worth a deeper dive.
293
00:15:28,440 --> 00:15:28,940
Nikolay: Right.
294
00:15:29,280 --> 00:15:29,640
Right.
295
00:15:29,640 --> 00:15:30,040
Right.
296
00:15:30,040 --> 00:15:34,300
I just wanted to point out that
when people say Analyze, it's
297
00:15:34,300 --> 00:15:36,640
just 1 threaded, right?
298
00:15:37,120 --> 00:15:41,420
And you expect Postgres has a lot
of parallelism implemented.
299
00:15:41,940 --> 00:15:44,440
But when you run Analyze, it's
always single threaded.
300
00:15:44,680 --> 00:15:46,800
This is unexpected as well, right?
301
00:15:47,100 --> 00:15:47,540
Michael: Good 1.
302
00:15:47,540 --> 00:15:48,520
Yeah, I like that.
303
00:15:48,520 --> 00:15:51,640
Nikolay: It's kind of gotcha inside
gotcha we have matryoshka
304
00:15:51,700 --> 00:15:54,620
style gotcha here right Russian
doll style
305
00:15:54,620 --> 00:15:57,620
Michael: what do you do you recommend
doing like just kicking
306
00:15:57,620 --> 00:16:00,540
off a bunch of queries analyzed
tape like per table
307
00:16:00,540 --> 00:16:04,380
Nikolay: I recommend partition
I recommend vacuumdb
308
00:16:04,800 --> 00:16:05,780
Michael: nice okay
309
00:16:05,920 --> 00:16:08,680
Nikolay: And speed up and go full
speed inside maintenance window.
310
00:16:08,680 --> 00:16:09,940
Again, it's a different story.
311
00:16:10,200 --> 00:16:15,780
But this vacuumdb, it has
--jobs
312
00:16:15,780 --> 00:16:17,120
or -j.
313
00:16:17,440 --> 00:16:18,300
You can define.
314
00:16:18,300 --> 00:16:22,240
And usually, we take as many courses
we have on the server and
315
00:16:22,240 --> 00:16:24,780
go full speed inside maintenance
window to achieve.
316
00:16:25,120 --> 00:16:28,200
Analyze should be quite fast if
you don't do vacuum.
317
00:16:29,160 --> 00:16:33,540
There is also gotcha a little bit
in vacuumdb options because
318
00:16:33,600 --> 00:16:37,320
vacuumdb's, --analyze
will also do vacuum.
319
00:16:37,580 --> 00:16:38,200
So there's
320
00:16:38,200 --> 00:16:39,860
Michael: also analyze only or
321
00:16:39,860 --> 00:16:41,140
Nikolay: there is analyze only.
322
00:16:41,240 --> 00:16:43,120
Yeah, but it's easy to overlook.
323
00:16:43,340 --> 00:16:45,800
There's 1 more gotcha here inside
all this.
324
00:16:46,300 --> 00:16:51,560
When people go with manual single-threaded
analyze or maybe multi-threaded
325
00:16:51,820 --> 00:16:54,120
but just explicit analyze.
326
00:16:55,080 --> 00:16:59,960
I've like quickly, it was interesting,
I was thinking someone
327
00:16:59,960 --> 00:17:01,560
said analyze can be super expensive.
328
00:17:01,560 --> 00:17:05,140
I agree, but even if it's like,
if the default_statistics_target
329
00:17:05,140 --> 00:17:06,780
is 1000, it's not that expensive.
330
00:17:06,780 --> 00:17:11,020
But back to this, can we throttle
it?
331
00:17:12,520 --> 00:17:16,100
For example, you want it to go
very slow, because autovacuum
332
00:17:16,100 --> 00:17:19,660
has autovacuum, doesn't have actually
333
00:17:19,660 --> 00:17:20,940
Michael: a vacuum_cost_delay also?
334
00:17:21,180 --> 00:17:24,060
Nikolay: Yes, there is
vacuum_cost_delay and vacuum_cost_limit.
335
00:17:25,360 --> 00:17:28,440
By default, it's off because I
think the cost limit is 0, meaning
336
00:17:28,440 --> 00:17:30,040
that it's not checked at all.
337
00:17:30,400 --> 00:17:33,720
Not cost limit, cost delay is 0,
like no check.
338
00:17:34,120 --> 00:17:38,820
But autovacuum has like mirrored
pair of these settings.
339
00:17:39,560 --> 00:17:40,460
It's throttled.
340
00:17:41,060 --> 00:17:43,520
Long story short, autovacuum is
throttled usually.
341
00:17:44,340 --> 00:17:47,440
And we actually usually fight with
our customers a little bit
342
00:17:47,440 --> 00:17:51,000
to increase this, make it even
more aggressive.
343
00:17:52,800 --> 00:17:56,040
And managed providers already did
part of that job, which is
344
00:17:56,040 --> 00:17:56,540
good.
345
00:17:56,880 --> 00:18:00,840
But if we run it manually, it's
not throttled.
346
00:18:00,840 --> 00:18:02,140
It will go full speed.
347
00:18:02,200 --> 00:18:06,960
I doubt you will need to throttle
it, but some people want, okay,
348
00:18:06,960 --> 00:18:08,040
let's throttle it.
349
00:18:08,100 --> 00:18:09,340
Question, how?
350
00:18:09,620 --> 00:18:14,440
We have a vacuum limit, vacuum_cost_limit, vacuum_cost_delay.
351
00:18:15,040 --> 00:18:19,060
We can set vacuum_cost_delay from default 0 to some point.
352
00:18:19,600 --> 00:18:23,320
But is it about Analyze, or it's only about vacuum?
353
00:18:23,320 --> 00:18:25,680
Based on just the naming, it's not about Analyze.
354
00:18:25,680 --> 00:18:27,040
It's about vacuum only.
355
00:18:28,140 --> 00:18:28,640
Michael: Right?
356
00:18:28,680 --> 00:18:29,900
Yeah, that would be my guess.
357
00:18:29,900 --> 00:18:33,780
But by the line of your questioning, I'm guessing it does affect
358
00:18:33,780 --> 00:18:34,620
your analysis.
359
00:18:34,820 --> 00:18:35,220
Nikolay: Right.
360
00:18:35,220 --> 00:18:39,620
I go to documentation and I see vacuum_cost_limit, vacuum_cost_delay,
361
00:18:39,620 --> 00:18:40,680
I think.
362
00:18:40,680 --> 00:18:41,740
And I see description.
363
00:18:41,980 --> 00:18:44,560
They talk only about vacuum, they don't talk about analysis.
364
00:18:45,040 --> 00:18:47,740
So I make conclusion, it's only about vacuum.
365
00:18:48,400 --> 00:18:53,560
But some part of my very long-term memory tells me, is it really
366
00:18:53,560 --> 00:18:54,060
so?
367
00:18:55,840 --> 00:18:59,540
And then Sadek Dusty, who helped me a lot with, and still helping
368
00:18:59,540 --> 00:19:03,240
sometimes when I write at how-to's and reviews How-To's, I'm
369
00:19:03,240 --> 00:19:06,060
very thankful for that.
370
00:19:06,880 --> 00:19:08,660
I have already 94 how-tos.
371
00:19:09,720 --> 00:19:11,660
So I wrote how-to, how-to Analyze.
372
00:19:11,930 --> 00:19:14,980
And right now I need to add this.
373
00:19:16,220 --> 00:19:19,140
vacuum_cost_limit, vacuum_cost_delay, they affect Analyze.
374
00:19:19,440 --> 00:19:23,680
If you scroll up to the beginning of section, you will see that
375
00:19:23,680 --> 00:19:26,340
it talks about both vacuum and Analyze.
376
00:19:26,800 --> 00:19:30,680
And we also, using AI, I checked source code and quickly found
377
00:19:30,680 --> 00:19:35,200
that there is a function called vacuumExec, which works with
378
00:19:35,200 --> 00:19:36,540
both vacuum and Analyze.
379
00:19:36,820 --> 00:19:40,040
And this confusion comes from source code, propagates to the
380
00:19:40,040 --> 00:19:42,480
documentation, and then to our heads, right?
381
00:19:42,560 --> 00:19:43,940
This is gotcha as well.
382
00:19:43,940 --> 00:19:47,460
So you can use vacuum_cost_limit, vacuum_cost_delay, to throttle
383
00:19:47,600 --> 00:19:51,300
Analyze, although I usually don't do it because I think we need
384
00:19:51,300 --> 00:19:52,320
to go full speed.
385
00:19:53,400 --> 00:19:55,900
Michael: And in the 1 example we're talking about here, we want
386
00:19:55,900 --> 00:19:57,280
to go faster, not slower.
387
00:19:57,660 --> 00:19:58,880
Nikolay: Right, right.
388
00:19:59,340 --> 00:20:00,560
But it's interesting, right?
389
00:20:00,660 --> 00:20:02,080
So there is some small confusion.
390
00:20:02,080 --> 00:20:04,060
I think there are many such confusions.
391
00:20:04,820 --> 00:20:06,540
But they are slowly fixed.
392
00:20:06,680 --> 00:20:08,400
They are slowly being fixed.
393
00:20:08,400 --> 00:20:10,860
Michael: Great example of 1 where the documentation
394
00:20:10,920 --> 00:20:13,760
wasn't helpful in avoiding that 1.
395
00:20:13,940 --> 00:20:14,780
So yeah, nice.
396
00:20:15,120 --> 00:20:17,960
I've got a few more beginner-friendly ones that maybe we could
397
00:20:17,960 --> 00:20:18,740
rattle through.
398
00:20:18,740 --> 00:20:23,560
I'm not even sure you'd consider them all gotchas, but 1 relates
399
00:20:27,620 --> 00:20:28,280
of places.
400
00:20:29,040 --> 00:20:30,900
I think that not only catches...
401
00:20:30,920 --> 00:20:32,660
Well, you don't think it's a gotcha?
402
00:20:33,120 --> 00:20:36,220
Nikolay: I think we should exclude
this on the same, like, we're
403
00:20:36,220 --> 00:20:41,540
using the same approach as now
because it's a huge bag of, yeah.
404
00:20:41,920 --> 00:20:42,320
Michael: Cool.
405
00:20:42,320 --> 00:20:45,080
And then another 1 that I see catch
out, well, a couple that
406
00:20:45,080 --> 00:20:48,280
I see catch out beginners, again,
maybe this is another huge
407
00:20:48,280 --> 00:20:53,400
topic, but access exclusive locks
on like just basically DDL
408
00:20:54,300 --> 00:20:58,080
blocking selects, like blocking
every, blocking inserts and like
409
00:20:58,080 --> 00:21:02,620
you know all sorts of people getting,
I think people don't realize
410
00:21:02,620 --> 00:21:05,680
because if they're working on small
databases at first, they
411
00:21:05,680 --> 00:21:09,860
start to grow in confidence of
how to do things.
412
00:21:10,080 --> 00:21:14,620
And then it only catches them out
once the startup's got really
413
00:21:14,620 --> 00:21:17,260
successful and the table's much
bigger, that kind of thing.
414
00:21:17,680 --> 00:21:23,080
Nikolay: Yeah, I think there is
some memes with Gauss distribution,
415
00:21:23,080 --> 00:21:24,500
or how it's called, right?
416
00:21:24,680 --> 00:21:25,660
Gaussian distribution.
417
00:21:25,760 --> 00:21:29,840
And first, I think schema changes
are painful.
418
00:21:31,300 --> 00:21:34,660
In the, like, schema changes are
super painful.
419
00:21:34,660 --> 00:21:36,920
They require expertise, like, beginner,
right?
420
00:21:37,040 --> 00:21:41,460
Then in the middle, you can imagine,
oh, Postgres has transactional
421
00:21:41,580 --> 00:21:44,720
DDL, everything is fine, we just
need to wrap everything into
422
00:21:44,720 --> 00:21:48,400
1 transaction and, and rely on
Postgres great capabilities of
423
00:21:48,400 --> 00:21:49,040
transactional DDL.
424
00:21:49,040 --> 00:21:50,860
Michael: Yeah, or just concurrently
and think
425
00:21:50,860 --> 00:21:53,400
Nikolay: yeah Yeah, MVCC works.
426
00:21:53,400 --> 00:21:56,680
Well, it doesn't block sell Excel
X are always working you can
427
00:21:56,680 --> 00:22:01,580
you can have a lot of Like exciting
stuff in the middle and then
428
00:22:01,580 --> 00:22:05,360
on the on the right you say post
this doesn't look was this has
429
00:22:05,360 --> 00:22:08,520
come Transactional detail, but
you cannot use it
430
00:22:09,040 --> 00:22:11,280
Michael: Well the in on the right
has to be the same as the left,
431
00:22:11,280 --> 00:22:11,720
doesn't it?
432
00:22:11,720 --> 00:22:13,040
Schema changes are painful.
433
00:22:13,380 --> 00:22:17,320
Nikolay: Yes, they are painful,
transactional DDL cannot be used
434
00:22:17,320 --> 00:22:24,380
in many, many cases, and you can
shoot your feet very well many
435
00:22:24,380 --> 00:22:24,880
times.
436
00:22:29,600 --> 00:22:31,120
So this is it, I think.
437
00:22:31,120 --> 00:22:32,940
And a lot of gotchas there.
438
00:22:33,740 --> 00:22:36,180
Michael: Another 1 that's not necessarily,
I'm not sure if this
439
00:22:36,180 --> 00:22:38,400
counts as a gotcha, I'd be interested
in your opinion but it
440
00:22:38,400 --> 00:22:41,780
does have seen it catch people
out and I guess it's a little
441
00:22:41,780 --> 00:22:45,340
bit of a foot gun and that's you
know you see the memes about
442
00:22:45,340 --> 00:22:48,620
this as well actually DELETE or
UPDATE without a WHERE clause
443
00:22:48,620 --> 00:22:52,000
and then just suddenly seeing you
know instead of 5 updated.
444
00:22:55,080 --> 00:22:57,720
But if you think like it's not
Postgres, why do you say it's
445
00:22:57,720 --> 00:22:59,120
not Postgres out of interest?
446
00:22:59,340 --> 00:23:02,360
Nikolay: Because the SQL standard
does it like defines this and
447
00:23:02,360 --> 00:23:06,540
any relational database which follows
SQL standard to some extent
448
00:23:07,120 --> 00:23:07,940
has it.
449
00:23:08,760 --> 00:23:09,260
Michael: Yeah.
450
00:23:10,140 --> 00:23:17,360
But I've seen clients catch these,
But the ones that ship, well,
451
00:23:17,360 --> 00:23:18,980
the only, the psql doesn't.
452
00:23:19,120 --> 00:23:22,480
So I don't think it's unreasonable
that Postgres does it this
453
00:23:22,480 --> 00:23:24,980
way, but I've definitely seen it
catch people out.
454
00:23:25,440 --> 00:23:26,100
Nikolay: I agree.
455
00:23:26,580 --> 00:23:27,880
Blame SQL standard.
456
00:23:28,140 --> 00:23:30,780
And there is extension to forbid
it.
457
00:23:30,780 --> 00:23:35,080
And also it was maybe 1 of the
very first hacking sessions with
458
00:23:35,080 --> 00:23:35,500
Andrei.
459
00:23:35,500 --> 00:23:43,000
We implemented some setting, GUC
setting in Postgres, which would
460
00:23:43,000 --> 00:23:48,820
allow administrators to, I don't
think error, warning, like completely
461
00:23:48,820 --> 00:23:50,380
forbid or just warn, I don't remember.
462
00:23:50,380 --> 00:23:52,220
I think error should be here.
463
00:23:52,540 --> 00:23:55,680
But it was not accepted, of course,
because I think it was discussed
464
00:23:55,680 --> 00:23:56,420
many times.
465
00:23:57,280 --> 00:23:58,480
I mean, it's possible.
466
00:23:58,940 --> 00:24:02,960
And right now, as I see, I think
PostgREST does it, right?
467
00:24:03,340 --> 00:24:03,840
PostgREST...
468
00:24:04,460 --> 00:24:05,440
Michael: Oh, does it?
469
00:24:05,640 --> 00:24:08,800
Nikolay: So usually right now it's
sold, if there is some middleware,
470
00:24:08,940 --> 00:24:09,840
it's sold there.
471
00:24:10,320 --> 00:24:15,220
So if you develop API using PostgREST,
for example, I think, Maybe
472
00:24:15,220 --> 00:24:17,220
I'm mistaken, but I think there
is a way.
473
00:24:17,320 --> 00:24:19,900
If there is no way, it's a good
idea to implement, actually.
474
00:24:19,900 --> 00:24:20,980
Michael: Yeah, it would be, yeah.
475
00:24:20,980 --> 00:24:26,820
Nikolay: Yeah, so if in URL of
your HTTP request of RESTful API,
476
00:24:27,080 --> 00:24:31,720
there is a command to run delete
without any filters, I think
477
00:24:31,720 --> 00:24:36,860
it will not do it it will not go
to progress with it so but inside
478
00:24:36,860 --> 00:24:42,380
database I don't I don't think
it's going to change right and
479
00:24:42,380 --> 00:24:44,080
we tried actually so
480
00:24:44,760 --> 00:24:48,060
Michael: yes with the well and
we tried what do you mean each
481
00:24:48,060 --> 00:24:49,120
right again
482
00:24:49,140 --> 00:24:51,900
Nikolay: we had a session yeah
we had a patch and they submitted
483
00:24:51,900 --> 00:24:56,240
it, but it was a small discussion
and chances are close to 0
484
00:24:56,240 --> 00:24:58,860
that it will be successful.
485
00:24:59,840 --> 00:25:02,060
Michael: Patch in psql or somewhere
else?
486
00:25:02,220 --> 00:25:03,340
Nikolay: No, not in psql.
487
00:25:03,580 --> 00:25:08,340
We wanted to have a Postgres
setting, GUC setting, to just
488
00:25:08,340 --> 00:25:12,840
allow administrators to forbid
unspecified, I don't remember
489
00:25:12,840 --> 00:25:16,500
how we called it, maybe unspecified
delete and update, when you
490
00:25:16,500 --> 00:25:19,020
don't have the WHERE clause at
all.
491
00:25:19,800 --> 00:25:21,120
Just like,
492
00:25:21,220 --> 00:25:21,720
Michael: cool,
493
00:25:22,060 --> 00:25:22,820
Nikolay: don't do it.
494
00:25:22,820 --> 00:25:26,260
There's a truncate for if you want
to hit right an update of
495
00:25:26,260 --> 00:25:30,900
whole table I don't know yeah but
again like right now it's in
496
00:25:30,900 --> 00:25:33,700
middleware usually sold in middle
where You can have triggers
497
00:25:33,700 --> 00:25:35,900
or something to protect yourself
if you want.
498
00:25:36,300 --> 00:25:38,960
Or this extension if you're on
self-managed Postgres.
499
00:25:38,960 --> 00:25:40,540
There is some extension for it.
500
00:25:40,760 --> 00:25:44,840
I wanted to mention 1 thing, step
back to DDL.
501
00:25:45,420 --> 00:25:51,000
My favorite example is, do you
think just adding a Column, you
502
00:25:51,000 --> 00:25:55,240
cannot put your traffic down or
your Database down?
503
00:25:55,240 --> 00:25:57,580
You can, if it cannot acquire Lock.
504
00:25:57,800 --> 00:26:01,660
It starts blocking all Queries
to this Table, even SELECTs.
505
00:26:02,580 --> 00:26:05,780
Like, I cannot acquire Lock, everyone
else can wait.
506
00:26:05,900 --> 00:26:11,540
Even SELECTs who come with access
Share Lock, don't touch this.
507
00:26:12,040 --> 00:26:12,760
That's it.
508
00:26:13,320 --> 00:26:14,340
And that's not good.
509
00:26:14,680 --> 00:26:17,660
And this is super unexpected and
a super big surprise.
510
00:26:18,720 --> 00:26:22,000
Michael: Yeah, especially because
you could even test that.
511
00:26:22,580 --> 00:26:27,620
You could even make a fork of production
or clone it run that
512
00:26:27,620 --> 00:26:31,520
on its own in isolation where there
is no Lock and it runs super
513
00:26:31,520 --> 00:26:35,540
fast so you think this is safe
but even though it was super fast
514
00:26:35,540 --> 00:26:39,720
it does require that heavy Lock
and that blocks everything else
515
00:26:39,720 --> 00:26:41,780
definitely a gotcha that's a great
1
516
00:26:41,800 --> 00:26:45,480
Nikolay: yeah yeah and there are
many others in the area of DDL
517
00:26:45,480 --> 00:26:51,600
but this I find like affecting
every single project which had
518
00:26:51,660 --> 00:26:55,900
like at least some growth like
I don't like to 1000 TPS and it's
519
00:26:55,900 --> 00:26:58,820
already noticeable it's not noticeable
in tiny projects
520
00:27:00,140 --> 00:27:02,900
Michael: yeah yeah which I think
is part is kind of part of the
521
00:27:02,900 --> 00:27:06,100
problem right or like at least
makes it worse because anybody
522
00:27:06,100 --> 00:27:10,920
that gains experience on smaller
projects as they grow Get some
523
00:27:10,920 --> 00:27:13,940
confidence that these things work
or they're fine and then it
524
00:27:13,940 --> 00:27:15,740
change changes at some point
525
00:27:16,320 --> 00:27:16,820
Nikolay: exactly
526
00:27:18,060 --> 00:27:20,140
Michael: so you've got a great
article in this actually I think
527
00:27:20,140 --> 00:27:24,900
that I can share about DDL it's
all about DDL changes I think
528
00:27:25,160 --> 00:27:28,860
Nikolay: yeah it's yeah yeah it's
this this 1 is definitely included
529
00:27:28,860 --> 00:27:33,180
I think this 1 like has a different
blog post about like I have
530
00:27:33,180 --> 00:27:37,980
few about Details okay what else
531
00:27:38,760 --> 00:27:41,720
Michael: well in that in that area
of making big changes partly
532
00:27:41,720 --> 00:27:45,200
by mistake you know that the DELETE
or UPDATE without WHERE Do
533
00:27:45,200 --> 00:27:48,660
you think people would expect to
be able to undo something?
534
00:27:48,940 --> 00:27:54,440
I'm not thinking just from people
with experience of relational
535
00:27:54,440 --> 00:27:58,520
databases, but the fact that if
you do something like that by
536
00:27:58,520 --> 00:28:02,080
mistake, that you have to go to
your backups to get that data
537
00:28:02,080 --> 00:28:02,580
back.
538
00:28:03,080 --> 00:28:06,260
If I was in my early 20s or just
out, you know, if I was in my
539
00:28:06,260 --> 00:28:10,120
teens, all other software I use
has the ability to undo something
540
00:28:10,120 --> 00:28:11,420
if I do it by mistake.
541
00:28:11,940 --> 00:28:16,220
So it does feel slightly unexpected,
potentially if I've grown
542
00:28:16,220 --> 00:28:19,640
up in that world, that I can make
1 mistake and not be able to
543
00:28:19,640 --> 00:28:19,960
undo it.
544
00:28:19,960 --> 00:28:21,220
Nikolay: And what Database you
can?
545
00:28:21,220 --> 00:28:22,440
I mean, of course, there are like...
546
00:28:22,440 --> 00:28:23,440
Michael: Yeah, I don't know.
547
00:28:23,440 --> 00:28:24,660
Nikolay: Time travel or...
548
00:28:25,840 --> 00:28:27,500
If branching is supported, you
can...
549
00:28:27,500 --> 00:28:32,140
But it's still like not super simple, right?
550
00:28:32,520 --> 00:28:33,720
Well, yeah, I don't know.
551
00:28:33,720 --> 00:28:36,800
I mean, there are several projects which try to solve this problem
552
00:28:36,820 --> 00:28:41,760
and I mean the data specific databases supporting branching for
553
00:28:41,760 --> 00:28:47,620
example or even other I think Have you heard about this new company
554
00:28:47,660 --> 00:28:49,520
where Michael Stonebraker is participating?
555
00:28:50,920 --> 00:28:51,060
Michael: I've
556
00:28:51,060 --> 00:28:53,000
heard of it, I don't know much about it.
557
00:28:53,000 --> 00:28:53,500
Nikolay: DBOps?
558
00:28:53,840 --> 00:28:54,840
Or how is it called?
559
00:28:54,840 --> 00:28:55,700
I don't remember.
560
00:28:55,920 --> 00:28:57,100
Not DBOps, DBOS.
561
00:28:58,700 --> 00:28:59,200
Michael: Yes.
562
00:29:00,180 --> 00:29:03,160
Nikolay: So I wonder if this feature will be inside it.
563
00:29:03,860 --> 00:29:04,700
I don't know.
564
00:29:04,740 --> 00:29:06,260
For me, it's not expected.
565
00:29:06,380 --> 00:29:12,100
I cannot name this gotcha because it's a hard problem, and we
566
00:29:13,140 --> 00:29:18,820
didn't get used to it, to having it, because it's rare.
567
00:29:19,710 --> 00:29:28,100
But if we go to young people's minds, there are many gotchas
568
00:29:28,100 --> 00:29:28,780
for them, right?
569
00:29:28,780 --> 00:29:30,700
Oh, this is working not as I expected.
570
00:29:32,080 --> 00:29:36,360
So naming is hard just because it should avoid gotchas.
571
00:29:36,380 --> 00:29:40,480
If you chose some name, you should think about other people and
572
00:29:40,480 --> 00:29:42,180
think to be very predictable.
573
00:29:42,980 --> 00:29:44,840
This is the art of naming.
574
00:29:45,440 --> 00:29:49,200
And we just discussed this vacuum_cost_limit affecting analyze.
575
00:29:50,140 --> 00:29:56,280
So yeah, and in young minds, gotchas, because gotchas world is
576
00:29:56,280 --> 00:30:00,740
much bigger because they don't understand the logic in many places,
577
00:30:00,740 --> 00:30:05,740
how it's like, like common practice in many places, right?
578
00:30:05,740 --> 00:30:08,540
And that's why many more unexpected situations.
579
00:30:09,640 --> 00:30:10,460
Michael: Yeah, fair.
580
00:30:11,000 --> 00:30:14,540
Nikolay: Yeah, by the way, if you run pg_dump on a very large
581
00:30:14,880 --> 00:30:21,400
database, like 1 table after another, And then we deal with snapshot,
582
00:30:21,400 --> 00:30:21,900
right?
583
00:30:22,580 --> 00:30:26,700
With snapshot, it's a repeatable read and snapshot.
584
00:30:26,820 --> 00:30:32,000
And even if you use multiple workers for pg_dump, they are synchronized
585
00:30:32,360 --> 00:30:33,780
reading from the same snapshot.
586
00:30:34,200 --> 00:30:38,100
But what if some table is dropped?
587
00:30:38,360 --> 00:30:40,340
Will it be present in this table?
588
00:30:41,040 --> 00:30:42,180
I'm not sure, actually.
589
00:30:42,880 --> 00:30:44,340
I just think there is a God check
590
00:30:44,340 --> 00:30:44,840
Michael: here.
591
00:30:45,660 --> 00:30:51,300
Nikolay: If during dump there are some schema changes, can we
592
00:30:51,300 --> 00:30:54,240
have some inconsistency in backups?
593
00:30:55,260 --> 00:30:56,580
Not in backups, in dumps.
594
00:30:56,580 --> 00:31:01,160
By the way, this confusion was resolved recently, right?
595
00:31:01,220 --> 00:31:06,040
We didn't mention it in the previous discussions of confusions,
596
00:31:06,060 --> 00:31:15,520
but the pg_dump page is not saying it's for dumps anymore.
597
00:31:15,940 --> 00:31:17,380
So dumps are not backups.
598
00:31:19,660 --> 00:31:20,880
Michael: That's coming.
599
00:31:21,960 --> 00:31:22,960
Nikolay: Yeah, in 2018.
600
00:31:23,100 --> 00:31:23,940
Okay, okay, okay.
601
00:31:23,940 --> 00:31:25,300
We will discuss this additionally.
602
00:31:25,640 --> 00:31:29,940
But this is a big confusion when
the computation says pg_dump
603
00:31:30,060 --> 00:31:31,080
is a backup tool.
604
00:31:31,080 --> 00:31:33,220
It's still so, even in 16.
605
00:31:33,760 --> 00:31:38,660
And now we have all rights to say
it's like all people who said
606
00:31:38,800 --> 00:31:42,500
pg_dump is not a backup tool, we
are right, because finally in
607
00:31:42,500 --> 00:31:44,040
18 it's already changed.
608
00:31:44,040 --> 00:31:47,340
I think it won't be reverted, I
hope so, this patch.
609
00:31:49,540 --> 00:31:54,800
But back to our topic, pg_dump can
be expected to be a tool for
610
00:31:54,800 --> 00:31:56,460
backups just because of documentation.
611
00:31:56,720 --> 00:32:01,320
Then you have quite a painful process
of realizing it's very
612
00:32:01,320 --> 00:32:02,320
bad for backups.
613
00:32:02,900 --> 00:32:06,600
So it's a gotcha, which is already
fixed in the future in Postgres
614
00:32:07,000 --> 00:32:07,500
18.
615
00:32:09,860 --> 00:32:18,900
And if we, in this area, pg_restore
doesn't run analyze, which
616
00:32:19,160 --> 00:32:24,620
hurts every second attempt to restore
a big database, even with
617
00:32:24,620 --> 00:32:26,620
experienced people like I am.
618
00:32:26,880 --> 00:32:29,920
Because, again, it's like with
pg_upgrade, we discussed it.
619
00:32:29,920 --> 00:32:33,400
pg_restore, You restore a huge
dump, you start working with
620
00:32:33,400 --> 00:32:38,940
it, but it's slow, and in plans
you see where you expect a simple
621
00:32:38,940 --> 00:32:42,520
index scan, you see bitmap scans,
bitmap index, bitmap heap scan,
622
00:32:42,520 --> 00:32:44,720
because there is no vacuum, there
is no analysis.
623
00:32:45,060 --> 00:32:50,580
It also should run on a vacuum
to collect visibility maps.
624
00:32:51,340 --> 00:32:51,840
Or
625
00:32:53,300 --> 00:32:56,980
Michael: it might not be unreasonable
to think that maybe backups
626
00:32:56,980 --> 00:32:59,980
would include the statistics and
then restore would restore the
627
00:32:59,980 --> 00:33:00,480
statistics.
628
00:33:01,400 --> 00:33:02,920
Nikolay: Physical backups, I agree.
629
00:33:03,280 --> 00:33:04,860
Logical backups, I disagree.
630
00:33:06,680 --> 00:33:10,260
You don't include indexes, which
is derivative from data itself.
631
00:33:10,260 --> 00:33:12,840
Statistics is also derivative of
data.
632
00:33:13,660 --> 00:33:16,120
So you include description, like
create index.
633
00:33:16,320 --> 00:33:20,520
There should be, maybe should be
some word like analyze in there.
634
00:33:22,060 --> 00:33:25,620
I wanted to say create statistics,
but it was analyzed already.
635
00:33:26,180 --> 00:33:27,100
There's such word.
636
00:33:27,500 --> 00:33:28,200
Why restore?
637
00:33:28,200 --> 00:33:31,420
And restore could run it.
638
00:33:31,420 --> 00:33:37,280
If we use pg_restore -j
8, for example, 8 parallel drops.
639
00:33:37,920 --> 00:33:43,160
In this case, why are we not recalculating
statistics?
640
00:33:44,100 --> 00:33:48,720
Right now, everyone who deals with
some automation, for example,
641
00:33:48,720 --> 00:33:52,200
for DBLab Engine, we need it when
provisioning is logical.
642
00:33:52,200 --> 00:33:55,440
So it's dump restore and we need
to move as fast as possible
643
00:33:55,440 --> 00:34:00,180
multiple jobs, multiple workers
for dump, multiple workers for
644
00:34:00,180 --> 00:34:00,680
restore.
645
00:34:01,100 --> 00:34:05,920
And then of course, vacuumdb,
in this case, --analyze
646
00:34:05,920 --> 00:34:10,840
to have vacuum as well and also
-j, but People forget about
647
00:34:10,840 --> 00:34:14,340
this and forget forgetting means
like you expect it will be fine,
648
00:34:14,340 --> 00:34:20,220
but if you don't run analyze yourself
ideally in multiple threads
649
00:34:20,220 --> 00:34:23,400
and multiple workers using multiple
workers in this case performance
650
00:34:23,400 --> 00:34:28,200
will be very bad and people start
thinking oh Postgres is slow
651
00:34:30,040 --> 00:34:33,540
have you heard about this Like
I restore from dump and it's slow.
652
00:34:35,140 --> 00:34:39,400
Michael: I have to admit I haven't
heard that complaint, no.
653
00:34:40,860 --> 00:34:46,240
Nikolay: Okay, I'm hearing it and
I'm doing it myself almost
654
00:34:46,240 --> 00:34:47,060
20 years.
655
00:34:47,088 --> 00:34:49,172
I know about this.
656
00:34:49,200 --> 00:34:51,500
Michael: No, I'm not saying it
doesn't exist, I just haven't,
657
00:34:51,500 --> 00:34:54,880
you know, maybe it's just not the
category of problem maybe what
658
00:34:54,880 --> 00:34:58,940
happens when people experience
that is they don't noticed online
659
00:34:59,380 --> 00:35:02,860
or I didn't know it's or they don't
post they just go try something
660
00:35:02,860 --> 00:35:03,360
else
661
00:35:03,520 --> 00:35:07,120
Nikolay: yeah it's it's not a big
deal if you restore, and it's
662
00:35:07,120 --> 00:35:10,760
working, and then you want to deal
with it 1 day later.
663
00:35:10,760 --> 00:35:14,120
Because probably, likely, autovacuum
will do it.
664
00:35:14,600 --> 00:35:18,620
But If you expect to run fast queries
immediately after restoration
665
00:35:18,920 --> 00:35:24,000
from a dump, I'm talking about
something which is 100% very well
666
00:35:24,000 --> 00:35:27,940
known to everyone, who is at least
a little bit experienced.
667
00:35:28,700 --> 00:35:32,000
But it doesn't make it non-gotcha,
it's still gotcha.
668
00:35:34,360 --> 00:35:39,440
That pg_restore doesn't calculate
statistics and doesn't run Vacuum.
669
00:35:42,040 --> 00:35:44,620
Michael: I mean it's quite remarkable,
I know we could go on
670
00:35:44,620 --> 00:35:47,960
with this list for quite a while
and there's like varying levels
671
00:35:47,960 --> 00:35:53,000
of gotchas but I like that I like
the list you sent me how how
672
00:35:53,000 --> 00:35:57,840
short and brief it is and I I really
think for many other databases
673
00:35:58,320 --> 00:36:02,760
it would be a much much longer
list I listened to well you're
674
00:36:02,760 --> 00:36:06,260
listening to your experience of
you know a couple of days of
675
00:36:06,260 --> 00:36:10,840
trying to use MySQL at the beginning,
and recently I was listening
676
00:36:10,840 --> 00:36:14,820
to an interview with Tom Lane,
and he mentioned, like, checking
677
00:36:14,820 --> 00:36:19,540
out MySQL at the beginning and
not liking a few things about
678
00:36:19,540 --> 00:36:19,940
it.
679
00:36:19,940 --> 00:36:22,100
And that feels like a really common
experience.
680
00:36:22,540 --> 00:36:25,920
And having worked with commercial
databases like SQL Server and
681
00:36:25,920 --> 00:36:32,080
Oracle, that often move much faster
in terms of adding features
682
00:36:32,080 --> 00:36:33,940
that enterprise clients really
want.
683
00:36:34,120 --> 00:36:39,240
There's just so many more gotchas
that result from processes
684
00:36:39,360 --> 00:36:39,800
like that.
685
00:36:39,800 --> 00:36:41,120
So I imagine I could be wrong.
686
00:36:41,120 --> 00:36:44,620
Nikolay: I think Postgres has lots
of gotchas, lots of them.
687
00:36:45,300 --> 00:36:47,580
Michael: But compared to other
relational databases?
688
00:36:48,340 --> 00:36:51,360
Nikolay: Yeah, it's a complex system,
all complex systems have
689
00:36:51,360 --> 00:36:52,280
a lot of gotchas.
690
00:36:52,600 --> 00:36:57,920
Some of them are just very niche,
very narrow and deep and so
691
00:36:57,920 --> 00:36:58,420
on.
692
00:36:58,940 --> 00:37:01,760
Some of them are like nobody knows
about them.
693
00:37:01,760 --> 00:37:04,900
For example, SELECT INTO.
694
00:37:06,820 --> 00:37:09,740
This is what you can write inside
PL/pgSQL, right?
695
00:37:10,080 --> 00:37:15,140
So you write a FUNCTION or TRIGGER,
and you write SELECT INTO
696
00:37:15,300 --> 00:37:17,560
some variable, blah, blah, blah.
697
00:37:17,560 --> 00:37:20,860
And then you think, OK, this SELECT
is like maybe it's complex
698
00:37:20,860 --> 00:37:21,760
SELECT, actually.
699
00:37:22,380 --> 00:37:26,040
Subselect or, I don't know, joins
and so on.
700
00:37:26,040 --> 00:37:29,360
But in the end, you have a scalar
or something, and you select
701
00:37:29,600 --> 00:37:31,680
into a variable inside PL/pgSQL.
702
00:37:31,800 --> 00:37:34,240
And then you think, I want to understand
the plan, or I want
703
00:37:34,240 --> 00:37:38,940
to just run it and try to troubleshoot,
and you put it to psql,
704
00:37:39,840 --> 00:37:40,840
what will happen?
705
00:37:40,840 --> 00:37:45,860
If you put SELECT INTO blah blah
blah, and then some regular
706
00:37:45,920 --> 00:37:49,380
select from where order by you
know
707
00:37:49,380 --> 00:37:52,620
Michael: just an error no what
happens
708
00:37:52,900 --> 00:37:54,240
Nikolay: it will create a table
709
00:37:56,120 --> 00:37:57,120
Michael: oh okay yeah
710
00:37:57,120 --> 00:38:01,360
Nikolay: go select into is 1 of
your lights it's great table
711
00:38:02,420 --> 00:38:06,140
This I think just should be removed,
like completely removed,
712
00:38:06,380 --> 00:38:06,880
deprecated.
713
00:38:07,900 --> 00:38:10,300
Select into creating a table, it's
a DDL.
714
00:38:15,140 --> 00:38:17,580
This is definitely a gotcha for
everyone.
715
00:38:18,840 --> 00:38:21,540
Michael: Yes, imagine all those
parsers that just...
716
00:38:21,820 --> 00:38:25,240
I know this is flawed for multiple
reasons, but look at any query
717
00:38:25,240 --> 00:38:28,140
that starts with SELECT, and like,
oh, it's a read query.
718
00:38:28,200 --> 00:38:32,780
Nikolay: Well, yeah, usually we
say SELECT for update is acquiring
719
00:38:32,860 --> 00:38:35,280
a heavy lock, blocking all writes.
720
00:38:36,220 --> 00:38:42,300
Yes, blocking all writes on these
rows, particular rows, not
721
00:38:42,380 --> 00:38:43,280
the whole table.
722
00:38:43,620 --> 00:38:46,780
But Select can create a table.
723
00:38:47,180 --> 00:38:49,700
And we have create table as select
already.
724
00:38:49,840 --> 00:38:53,180
And this is what all people use,
I think, who need it.
725
00:38:53,600 --> 00:38:59,440
So select into probably just some
very old stuff that could be
726
00:38:59,440 --> 00:39:01,080
potentially removed, I think.
727
00:39:01,400 --> 00:39:03,280
Michael: If it's not in the SQL
standard
728
00:39:05,200 --> 00:39:09,560
Nikolay: oh it's a good point if
it is no chances right
729
00:39:09,780 --> 00:39:13,700
Michael: yeah well probably not
no cool anything else you want
730
00:39:13,700 --> 00:39:14,840
to make sure we covered
731
00:39:15,420 --> 00:39:18,480
Nikolay: maybe it's enough I think
we covered less than 1% of
732
00:39:18,480 --> 00:39:19,620
what we could.
733
00:39:19,700 --> 00:39:20,740
This is my feeling.
734
00:39:20,740 --> 00:39:21,640
What do you think?
735
00:39:22,240 --> 00:39:25,560
Michael: Well, it depends what
you count as gotchas and how niche
736
00:39:25,560 --> 00:39:26,640
you're willing to go.
737
00:39:26,640 --> 00:39:29,640
It turns out the more you know,
the more gotchas you know about,
738
00:39:29,640 --> 00:39:30,280
I guess.
739
00:39:31,220 --> 00:39:34,100
Nikolay: So I could not resist
and I checked the documentation.
740
00:39:34,640 --> 00:39:37,940
SQL standard uses SELECT INTO to
represent selecting values into
741
00:39:37,940 --> 00:39:43,380
a scalar variable of a host program
rather than creating a new
742
00:39:43,380 --> 00:39:43,700
table.
743
00:39:43,700 --> 00:39:47,220
It's definitely Postgresism and
I think it should be removed.
744
00:39:47,720 --> 00:39:49,340
Michael: Okay, cool, good 1.
745
00:39:50,500 --> 00:39:53,220
Nikolay: Good, okay, good chat,
maybe some kind of entertaining
746
00:39:53,240 --> 00:39:56,100
more than useful, but I enjoyed
it.
747
00:39:56,100 --> 00:39:56,820
I enjoyed it.
748
00:39:56,820 --> 00:39:57,540
Michael: Yeah, absolutely.
749
00:39:58,320 --> 00:40:02,660
And feel free to send us any more
that you've got or that you
750
00:40:02,660 --> 00:40:05,900
Nikolay: Maybe we should think
about specific areas like we did
751
00:40:05,900 --> 00:40:11,740
for for now and maybe we should
explore some areas from this
752
00:40:11,740 --> 00:40:13,320
perspective what can be unexpected
753
00:40:14,340 --> 00:40:16,680
Michael: Yeah, for sure. Thanks
so much.
754
00:40:16,680 --> 00:40:17,220
Nikolay.
755
00:40:17,220 --> 00:40:18,180
Catch you next week.
756
00:40:18,180 --> 00:40:18,240
Nikolay: Thank you.
757
00:40:18,240 --> 00:40:18,560
You too.
00:00:00,060 --> 00:00:02,600
Michael: Hello and welcome to PostgresFM, a weekly show about
2
00:00:02,600 --> 00:00:03,540
all things PostgreSQL.
3
00:00:03,740 --> 00:00:05,580
I am Michael, founder of pgMustard.
4
00:00:05,680 --> 00:00:07,640
This is Nikolay, founder of Postgres.AI.
5
00:00:07,640 --> 00:00:08,460
Hello Nikolay.
6
00:00:08,940 --> 00:00:10,300
Nikolay: Hi Michael, how are you?
7
00:00:10,860 --> 00:00:12,280
Michael: I'm good, how are you?
8
00:00:12,560 --> 00:00:13,280
Nikolay: Very good.
9
00:00:13,580 --> 00:00:15,660
Let's talk about some crazy stuff.
10
00:00:16,160 --> 00:00:20,040
Michael: I chose the topic this week and it was a listener suggestion,
11
00:00:20,280 --> 00:00:24,020
it's Postgres gotchas and we've had a short discussion before
12
00:00:24,020 --> 00:00:26,700
this call about what we should even count as gotchas.
13
00:00:27,400 --> 00:00:30,620
So how do you define it, what do you think of when you hear Postgres
14
00:00:30,620 --> 00:00:31,120
gotcha?
15
00:00:31,580 --> 00:00:35,160
Nikolay: Well if you for example run, I don't know, like SELECT
16
00:00:35,360 --> 00:00:39,980
5/2, what will you get?
17
00:00:41,580 --> 00:00:43,220
Michael: Is this like data type casting?
18
00:00:43,740 --> 00:00:47,000
Nikolay: Right right well it's not Postgres related I think it's
19
00:00:47,040 --> 00:00:51,140
SQL related but still what do you expect to get?
20
00:00:51,180 --> 00:00:54,560
Normal person would expect 2.5, right?
21
00:00:55,260 --> 00:00:58,300
But you will get, and I just double checked because I always...
22
00:00:59,220 --> 00:01:02,260
I'm always like thinking, am I right?
23
00:01:02,580 --> 00:01:05,580
So you're getting 2, so 5.
24
00:01:05,940 --> 00:01:08,740
Michael: 0 wow, I actually thought it was going to be 3.
25
00:01:13,700 --> 00:01:15,700
Nikolay: We probably have 2 things to discuss here.
26
00:01:15,700 --> 00:01:19,560
First is of course integer and integer, right?
27
00:01:19,560 --> 00:01:23,000
Results should be integer, so there's no decimal, there's no
28
00:01:23,000 --> 00:01:24,820
point here, there's no dot.
29
00:01:25,280 --> 00:01:27,680
And, but 2 or 3?
30
00:01:29,340 --> 00:01:31,600
Rounding or flooring, right?
31
00:01:31,640 --> 00:01:35,280
Michael: Yeah, because like rounding conventions at least where
32
00:01:35,280 --> 00:01:40,600
I grew up we generally round up from 0.5 but not clearly not
33
00:01:40,600 --> 00:01:45,560
here anyway I like this almost this definition which is something
34
00:01:45,860 --> 00:01:50,820
where you may expect 1 outcome but a different outcome happens.
35
00:01:50,860 --> 00:01:51,360
That's
36
00:01:51,560 --> 00:01:54,100
Nikolay: unexpected behavior basically in other words.
37
00:01:54,860 --> 00:01:57,900
Michael: Yeah, especially unexpected if you haven't read the
38
00:01:57,900 --> 00:01:58,400
documentation.
39
00:02:00,640 --> 00:02:04,740
Nikolay: Sometimes documentation also wrong or misleading or
40
00:02:05,020 --> 00:02:07,360
sometimes it's just confusing.
41
00:02:08,540 --> 00:02:09,220
Michael: Yeah fair enough.
42
00:02:09,220 --> 00:02:12,160
I just wanted an excuse to list a few things that are made very
43
00:02:12,160 --> 00:02:16,020
clear in the documentation, but I know people get confused by
44
00:02:16,020 --> 00:02:17,940
it because often they don't read that.
45
00:02:18,820 --> 00:02:22,280
Nikolay: You know, I'm curious, I actually found a good example,
46
00:02:22,280 --> 00:02:22,540
right?
47
00:02:22,540 --> 00:02:25,680
It's like probably a gotcha SQL, not Postgres, because
48
00:02:25,680 --> 00:02:30,040
I think it's maybe defined by standard, but, and this is super
49
00:02:30,040 --> 00:02:34,940
basic, but I'm wondering why indeed it's 2 not 3 because if you
50
00:02:34,940 --> 00:02:39,440
for example I what I did I double check of course I checked floor
51
00:02:39,480 --> 00:02:44,060
and round functions and of course
as expected floor I converted
52
00:02:44,060 --> 00:02:47,780
5 to numeric or just just to
53
00:02:47,780 --> 00:02:49,320
Michael: last with the colon colon
54
00:02:49,360 --> 00:02:52,360
Nikolay: you're right right so
the result is also numeric and
55
00:02:52,360 --> 00:02:59,480
then we have of course 2.500 like
so but then I checked floor
56
00:02:59,480 --> 00:03:03,800
gives me 2 round gives me 3 is
expected because 2.5 means like
57
00:03:03,800 --> 00:03:08,800
we need if you're rounding according
to their names for these
58
00:03:08,800 --> 00:03:09,860
rules, I don't remember, right?
59
00:03:09,860 --> 00:03:14,700
But usually 5 you go up, 4 you
go down, right?
60
00:03:15,540 --> 00:03:18,660
And it gives 3, Round gives 3.
61
00:03:18,660 --> 00:03:26,100
But I was thinking, okay, why 5
slash 2 integer and integer gives
62
00:03:26,100 --> 00:03:27,320
2 and not 3?
63
00:03:27,400 --> 00:03:29,200
Maybe because it uses 4.
64
00:03:30,180 --> 00:03:34,120
We could check the source code,
of course, but the next thing
65
00:03:34,120 --> 00:03:36,300
I checked is the final thing I
checked.
66
00:03:36,740 --> 00:03:40,160
5 converted to numeric slash 2
gives you 2.5.
67
00:03:40,260 --> 00:03:42,040
And then you convert back to int,
right?
68
00:03:42,040 --> 00:03:43,860
Again, double colon int.
69
00:03:44,380 --> 00:03:45,600
It gives 3.
70
00:03:46,300 --> 00:03:46,800
Amazing.
71
00:03:50,440 --> 00:03:55,940
So how come we have 2 if we don't
use type conversion, explicit
72
00:03:55,960 --> 00:03:57,320
type conversion at all?
73
00:03:58,080 --> 00:03:58,760
Any ideas?
74
00:03:59,760 --> 00:04:01,580
It was good gotcha to find.
75
00:04:01,960 --> 00:04:04,200
I always knew that it's 2 because
I demonstrated.
76
00:04:04,200 --> 00:04:06,920
I just didn't think like why.
77
00:04:07,500 --> 00:04:08,600
Now I think why.
78
00:04:08,940 --> 00:04:09,940
I have questions.
79
00:04:10,240 --> 00:04:13,780
Maybe there is some good explanation,
simple, but I can see easily
80
00:04:13,780 --> 00:04:15,040
that it can be gotcha.
81
00:04:15,480 --> 00:04:17,180
It can be considered gotcha.
82
00:04:17,860 --> 00:04:20,420
And let's agree on 1 more thing.
83
00:04:20,740 --> 00:04:22,400
We don't talk about nulls today.
84
00:04:23,920 --> 00:04:26,520
Michael: I actually did have them
on my list, but not to go into
85
00:04:26,520 --> 00:04:27,020
detail.
86
00:04:27,260 --> 00:04:30,580
Nikolay: We had a whole episode,
and this whole episode is telling
87
00:04:30,580 --> 00:04:36,000
like, nulls are surrounded by gotchas
both like standard defined
88
00:04:36,600 --> 00:04:41,040
standard produce and like global
SQL gotchas and local Postgres
89
00:04:41,040 --> 00:04:45,060
related gotchas as well for example
when you go to a race right
90
00:04:45,060 --> 00:04:49,460
Let's just exclude it because it's
a whole massive area.
91
00:04:49,900 --> 00:04:51,260
Michael: I think that's very sensible.
92
00:04:51,600 --> 00:04:53,800
And if you haven't listened to
that episode, I'll link it up
93
00:04:53,800 --> 00:04:54,740
in the show notes.
94
00:04:55,240 --> 00:04:58,940
Nikolay: Consider it to be fully
included here.
95
00:04:59,140 --> 00:04:59,640
Yeah.
96
00:05:00,080 --> 00:05:00,580
Right.
97
00:05:00,920 --> 00:05:03,680
Okay, let's maybe switch to your
ideas.
98
00:05:03,680 --> 00:05:06,400
I know you have a list, pull something
from it.
99
00:05:06,460 --> 00:05:09,940
Michael: Yeah, I've got a few that
I wanted to make sure we mentioned.
100
00:05:10,080 --> 00:05:14,180
I'm gonna start with some ones
I consider more beginner level
101
00:05:14,540 --> 00:05:17,580
gotchas and then maybe we can work
our way up a little bit.
102
00:05:17,620 --> 00:05:23,880
The first 1 I had is 1 I see all
the time in kind of forums every
103
00:05:23,880 --> 00:05:28,260
now and again on Reddit, quite
a few times in like the Postgres
104
00:05:28,260 --> 00:05:30,520
Slack, a few up on a few mailing
lists.
105
00:05:31,220 --> 00:05:35,760
People getting confused or annoyed
when they name objects in
106
00:05:35,760 --> 00:05:42,380
Postgres and they use mixed case,
so maybe camel case or some
107
00:05:42,380 --> 00:05:47,220
way of naming a table like for
example like a two-worded name
108
00:05:47,380 --> 00:05:50,640
and using capital letters for the
2 names and no space in between
109
00:05:50,640 --> 00:05:53,680
them that kind of thing and then
realizing the table is not called
110
00:05:53,680 --> 00:05:58,040
that behind the scenes and it's
all lowercase and if they've
111
00:05:58,120 --> 00:06:02,820
used an ORM or something to name
these at the ORM often puts
112
00:06:03,420 --> 00:06:07,500
quotes around those case names
so then they become cased in the
113
00:06:07,500 --> 00:06:08,000
database.
114
00:06:08,420 --> 00:06:13,300
So I think this whole area is like
a 1 big gotcha for beginners
115
00:06:14,440 --> 00:06:18,060
and the people who set up the schema
in the first place, if they
116
00:06:18,340 --> 00:06:22,340
do something like this, if they
don't just use lowercase object
117
00:06:22,340 --> 00:06:26,140
names, can really make life a bit
painful for everybody that
118
00:06:26,140 --> 00:06:29,680
comes after them having to double
quote everything.
119
00:06:30,180 --> 00:06:33,840
Nikolay: Yeah, especially Java
people like it.
120
00:06:34,300 --> 00:06:35,040
Michael: Oh, really?
121
00:06:35,140 --> 00:06:37,180
Nikolay: Yeah, I noticed.
122
00:06:37,940 --> 00:06:43,180
Usually, if we have a new customer
and we start discussing their
123
00:06:43,180 --> 00:06:47,780
database, we see some camel-stack-cased
table names.
124
00:06:47,780 --> 00:06:52,440
And I think, I'm already thinking,
are you Java guys?
125
00:06:52,440 --> 00:06:53,540
Yeah, there are.
126
00:06:53,940 --> 00:06:56,260
Usually, not always, but usually
so.
127
00:06:56,440 --> 00:07:00,520
And my previous startup was using
it camel-style.
128
00:07:03,420 --> 00:07:06,240
And we just decided to keep it
as is because it was inherited
129
00:07:06,260 --> 00:07:06,960
from some...
130
00:07:07,200 --> 00:07:09,260
I think it was in MySQL originally.
131
00:07:09,900 --> 00:07:14,020
Like, we started very lean, so
we borrowed some schema from some
132
00:07:14,020 --> 00:07:15,080
open source project.
133
00:07:15,480 --> 00:07:16,580
And it had it.
134
00:07:16,640 --> 00:07:20,680
And I just, knowing this very well,
I still decided to keep it.
135
00:07:20,680 --> 00:07:22,960
But the problem with double quotes
is not like...
136
00:07:22,960 --> 00:07:24,640
It's not a big deal, but when...
137
00:07:24,720 --> 00:07:27,760
You know what comes with quotes
usually, right?
138
00:07:28,580 --> 00:07:29,080
Backslashes.
139
00:07:30,480 --> 00:07:31,180
Michael: Oh, having...
140
00:07:31,180 --> 00:07:32,800
Yeah, having to escape them.
141
00:07:32,900 --> 00:07:34,920
Nikolay: Yeah, and you cannot escape
from this.
142
00:07:34,920 --> 00:07:37,400
You need to use it to escape.
143
00:07:37,660 --> 00:07:37,940
Right?
144
00:07:37,940 --> 00:07:39,980
I mean, yeah.
145
00:07:40,080 --> 00:07:44,780
And backslashes, if you have automation
in many languages, like
146
00:07:44,780 --> 00:07:46,100
sometimes it's nightmare.
147
00:07:46,960 --> 00:07:50,580
Right now we have an ongoing problem
with backslashes and escaping
148
00:07:51,040 --> 00:07:54,360
of quotes and double quotes in
our AI system.
149
00:07:54,440 --> 00:07:57,900
It's a combination of Python and
Bash actually.
150
00:07:58,520 --> 00:08:00,520
And yeah, it drives us crazy sometimes.
151
00:08:00,700 --> 00:08:03,220
We solved some problems, but not
all of them still.
152
00:08:03,580 --> 00:08:07,660
And when Yi needs to talk about
your table names and you give
153
00:08:07,660 --> 00:08:11,420
the schema with double quotes,
and then you want to experiment
154
00:08:11,480 --> 00:08:16,620
in DBLab to find some plans or
something, it sometimes is broken
155
00:08:16,620 --> 00:08:21,160
just because of problems with backslashes
and passing these pieces
156
00:08:21,220 --> 00:08:22,700
between different components.
157
00:08:24,060 --> 00:08:27,040
I would prefer keeping everything
lowercase, that's it.
158
00:08:27,040 --> 00:08:27,680
In post-process.
159
00:08:27,800 --> 00:08:28,300
Right?
160
00:08:29,440 --> 00:08:30,600
Snake style, right?
161
00:08:31,100 --> 00:08:31,600
Michael: Yeah.
162
00:08:31,620 --> 00:08:32,220
Nikolay: And that's it.
163
00:08:32,220 --> 00:08:33,640
And just forget about it.
164
00:08:35,220 --> 00:08:36,000
Michael: Yeah, plays.
165
00:08:36,140 --> 00:08:37,040
Pay for plays.
166
00:08:37,500 --> 00:08:40,440
Nikolay: I wanted to mention the
list of gotchas I saw actually
167
00:08:40,440 --> 00:08:44,960
this is like as we discussed right
before this recording I didn't
168
00:08:44,960 --> 00:08:49,780
know this the word gotcha until
2006 or 2007 and this is exactly
169
00:08:49,780 --> 00:08:52,860
when this list was published.
170
00:08:53,220 --> 00:08:56,500
And I remember we had 2 lists,
1 for Postgres and 1 for MySQL.
171
00:08:57,180 --> 00:09:00,840
For MySQL, it's outside of scope,
right?
172
00:09:01,100 --> 00:09:03,640
Again, even more than nulls.
173
00:09:03,820 --> 00:09:08,080
But this list, I'm looking at it
right now and I'm very first
174
00:09:08,080 --> 00:09:15,940
of all it's survived how many years
like it's insane 18 17 years.
175
00:09:16,860 --> 00:09:17,300
Wow.
176
00:09:17,300 --> 00:09:21,600
And I'm looking at this, it's quite
short list at SQLinfo.de,
177
00:09:23,100 --> 00:09:23,600
right?
178
00:09:24,480 --> 00:09:27,040
And almost everything is crossed
out.
179
00:09:27,980 --> 00:09:28,480
Good.
180
00:09:29,240 --> 00:09:31,640
Michael: Yeah, this I've never
seen this page before.
181
00:09:31,640 --> 00:09:32,740
This is really cool.
182
00:09:32,980 --> 00:09:36,980
And yeah, maybe more than half
of them have been cost
183
00:09:36,980 --> 00:09:37,480
down.
184
00:09:40,080 --> 00:09:41,760
Nikolay: Yeah, account start is very slow.
185
00:09:42,660 --> 00:09:44,120
Let's just laugh at it.
186
00:09:45,060 --> 00:09:47,140
Michael: Oh, and we had an episode
on that, right?
187
00:09:47,540 --> 00:09:48,840
Nikolay: I think we should.
188
00:09:48,840 --> 00:09:51,580
Unicode means UTF-8 left as well.
189
00:09:51,580 --> 00:09:52,400
Well, yeah.
190
00:09:53,740 --> 00:09:56,840
Yeah, constraint checking is interesting,
but maybe let's not
191
00:09:56,840 --> 00:09:57,620
dive into it.
192
00:09:57,620 --> 00:10:00,720
And finally, I wanted to highlight
what else is left.
193
00:10:00,720 --> 00:10:01,660
Only 4 items.
194
00:10:01,880 --> 00:10:02,880
5, Okay, 5.
195
00:10:02,880 --> 00:10:06,960
But 1 of them is upgrades, upgrades,
related stuff.
196
00:10:07,200 --> 00:10:12,100
And I was discussing on Twitter,
on X, I was discussing this
197
00:10:12,100 --> 00:10:13,940
topic over the last few days.
198
00:10:14,180 --> 00:10:20,260
I just checked documentation of
3 major managed Postgres providers.
199
00:10:20,840 --> 00:10:24,300
So RDS, Cloud SQL, and Azure Postgres.
200
00:10:25,240 --> 00:10:30,460
I saw that all of them say, okay,
upgrade is done, major upgrade.
201
00:10:30,600 --> 00:10:33,900
Now it's time, don't forget, now it's time to run ANALYZE.
202
00:10:33,900 --> 00:10:38,300
And they say ANALYZE like they give you a snippet, ANALYZE semicolon,
203
00:10:38,400 --> 00:10:41,220
which means it's single-threaded as well.
204
00:10:41,520 --> 00:10:43,860
First of all, they don't include it.
205
00:10:43,860 --> 00:10:46,800
None of them include it into automation.
206
00:10:47,620 --> 00:10:50,460
But we don't talk about managed Postgres providers today, we
207
00:10:50,460 --> 00:10:51,320
talk about Postgres.
208
00:10:52,500 --> 00:10:58,180
My question is why pg_upgrade does not include...
209
00:10:58,180 --> 00:11:01,220
It prints only some text in there, but who reads the text?
210
00:11:01,440 --> 00:11:05,140
Many people will say, for those who don't read, it's on their
211
00:11:05,140 --> 00:11:06,520
shoulders, it's their problem.
212
00:11:06,820 --> 00:11:08,460
But I cannot agree with it.
213
00:11:09,600 --> 00:11:14,340
Michael: I could even make a case for the gotcha here is that
214
00:11:14,340 --> 00:11:17,460
statistics are not preserved on major upgrade.
215
00:11:17,800 --> 00:11:23,860
I think if you asked somebody that didn't know whether they would
216
00:11:23,860 --> 00:11:27,900
expect the statistics to be wiped or to be preserved, somebody
217
00:11:27,900 --> 00:11:31,080
maybe doesn't understand how difficult it might be or like the
218
00:11:31,080 --> 00:11:34,640
catalog, like the reasons why they're not preserved, you'd be
219
00:11:34,640 --> 00:11:38,600
forgiven to think like in a in the most advanced open source
220
00:11:38,600 --> 00:11:42,600
database that that might be that might happen even though it's
221
00:11:42,600 --> 00:11:45,110
complicated and I think there has been some work.
222
00:11:45,110 --> 00:11:45,290
It should
223
00:11:45,290 --> 00:11:47,660
Nikolay: happen and Everyone agrees on it, just not solved.
224
00:11:48,280 --> 00:11:50,520
Michael: Yeah, so I think that's the main gotcha.
225
00:11:50,540 --> 00:11:54,280
And then, obviously, the solution at the moment is we need to
226
00:11:54,280 --> 00:11:55,060
want to analyze.
227
00:11:55,520 --> 00:11:56,980
Nikolay: Yeah, let's unwrap a little bit.
228
00:11:56,980 --> 00:11:59,860
So we talk about statistics, which is required for a planner
229
00:11:59,860 --> 00:12:01,720
to make right decisions.
230
00:12:02,300 --> 00:12:05,640
If the database is not trivial, like containing like 100 rows
231
00:12:05,640 --> 00:12:06,960
in each table, that's it.
232
00:12:06,960 --> 00:12:08,860
If it's not trivial, we need statistics.
233
00:12:09,520 --> 00:12:11,440
Without statistics, database is slow.
234
00:12:12,700 --> 00:12:17,680
And what happens, I think in a zillion cases, it happens.
235
00:12:17,920 --> 00:12:21,420
Like It's hard to estimate, but when I posted this tweet, I received
236
00:12:21,420 --> 00:12:29,120
several replies immediately that, oh, we got beaten by this badly.
237
00:12:31,400 --> 00:12:35,740
Some person wrote, we learned this hard way, obviously.
238
00:12:36,260 --> 00:12:38,460
And this is like what happens all the time.
239
00:12:38,460 --> 00:12:45,800
And recently, during summer, we also like failed to help a customer
240
00:12:45,800 --> 00:12:46,160
with it.
241
00:12:46,160 --> 00:12:48,580
Like we discussed major upgrades, but we...
242
00:12:48,680 --> 00:12:52,040
From now on, I'm pointing out, like, don't forget, don't forget,
243
00:12:52,040 --> 00:12:52,780
don't forget.
244
00:12:53,100 --> 00:12:55,960
But we discussed upgrades, we discussed some, like, complicated
245
00:12:56,040 --> 00:13:00,520
stuff, and then they went to upgrade, and next Monday they say,
246
00:13:00,520 --> 00:13:02,160
oh, today they are in Europe.
247
00:13:02,160 --> 00:13:06,220
So in the morning, it was already by the evening in Europe.
248
00:13:06,220 --> 00:13:10,380
And they say, we had nasty database incidents today because guess
249
00:13:10,380 --> 00:13:10,760
what?
250
00:13:10,760 --> 00:13:13,120
We forgot to run ANALYZE.
251
00:13:14,240 --> 00:13:18,480
And this is huge gotcha not only
by managed services, they could
252
00:13:18,480 --> 00:13:21,520
do it but I don't care too much
about them.
253
00:13:21,660 --> 00:13:23,040
This is a gotcha of pg_upgrade.
254
00:13:23,240 --> 00:13:26,140
I think it's very well understood,
there is work in progress
255
00:13:26,200 --> 00:13:31,980
for export and import of statistics,
like quite a long thread
256
00:13:31,980 --> 00:13:34,500
in hackers already and commitfest
entry.
257
00:13:34,900 --> 00:13:38,340
It's still not done, but there
is hope.
258
00:13:39,960 --> 00:13:41,400
There is 1 more thing here.
259
00:13:41,400 --> 00:13:44,940
So I think pg_upgrade definitely
should have it.
260
00:13:45,060 --> 00:13:48,220
And also pg_restore, but let's return
to it in a few minutes.
261
00:13:50,280 --> 00:13:54,780
So when someone says you need to
recalculate statistics yourself
262
00:13:55,240 --> 00:13:57,140
after upgrade, pg_upgrade.
263
00:13:58,920 --> 00:14:01,820
I definitely would expect pg_upgrade
to do this for sure.
264
00:14:02,020 --> 00:14:04,220
But okay, it just prints do it.
265
00:14:04,340 --> 00:14:07,420
pg_upgrade prints vacuumdb, I think,
no?
266
00:14:07,420 --> 00:14:10,280
Or in stages, or like vacuumdb
in stages.
267
00:14:10,280 --> 00:14:14,060
It has this vacuumdb analyze only
in stages.
268
00:14:14,060 --> 00:14:14,640
2 options.
269
00:14:14,640 --> 00:14:16,940
Analyze only means no vacuum and
just Analyze.
270
00:14:17,320 --> 00:14:23,420
In stages means first it gets only
1 bucket for each table, for
271
00:14:23,420 --> 00:14:25,320
each column actually, right?
272
00:14:25,520 --> 00:14:29,480
And then some midway until your...
273
00:14:29,480 --> 00:14:34,600
And then default_statistics_target
or individual column based
274
00:14:34,600 --> 00:14:36,180
setting for each column.
275
00:14:36,340 --> 00:14:39,780
default_statistics_target by default
is 100, 100 buckets.
276
00:14:40,560 --> 00:14:46,580
This is what defines how much Postgres
planner will know about
277
00:14:46,680 --> 00:14:48,780
distribution in each column, right?
278
00:14:48,780 --> 00:14:52,040
And it can be adjusted globally
or for individual columns.
279
00:14:52,840 --> 00:14:53,260
But...
280
00:14:53,260 --> 00:14:56,100
Michael: Almost like a sample size,
like the sample size increases
281
00:14:56,260 --> 00:14:57,320
of what it samples.
282
00:14:57,320 --> 00:14:57,560
Nikolay: Yeah.
283
00:14:57,560 --> 00:15:01,200
And I quickly realized this is
not what you want to do in OLTP,
284
00:15:01,220 --> 00:15:06,560
because in OLTP, you either include
Analyze inside maintenance
285
00:15:06,580 --> 00:15:06,980
window.
286
00:15:06,980 --> 00:15:11,180
In this case, there is no sense
to run it 3 times, or you just...
287
00:15:12,880 --> 00:15:14,940
Or that's it, there is only option
actually.
288
00:15:15,180 --> 00:15:19,440
Like, I don't trust in opening
gates with weak statistics.
289
00:15:19,680 --> 00:15:22,220
It will be like unpredictable again
incident.
290
00:15:23,080 --> 00:15:23,580
Michael: Yeah.
291
00:15:24,140 --> 00:15:24,820
Yeah, risky.
292
00:15:24,860 --> 00:15:28,080
But this feels like a topic that
might be worth a deeper dive.
293
00:15:28,440 --> 00:15:28,940
Nikolay: Right.
294
00:15:29,280 --> 00:15:29,640
Right.
295
00:15:29,640 --> 00:15:30,040
Right.
296
00:15:30,040 --> 00:15:34,300
I just wanted to point out that
when people say Analyze, it's
297
00:15:34,300 --> 00:15:36,640
just 1 threaded, right?
298
00:15:37,120 --> 00:15:41,420
And you expect Postgres has a lot
of parallelism implemented.
299
00:15:41,940 --> 00:15:44,440
But when you run Analyze, it's
always single threaded.
300
00:15:44,680 --> 00:15:46,800
This is unexpected as well, right?
301
00:15:47,100 --> 00:15:47,540
Michael: Good 1.
302
00:15:47,540 --> 00:15:48,520
Yeah, I like that.
303
00:15:48,520 --> 00:15:51,640
Nikolay: It's kind of gotcha inside
gotcha we have matryoshka
304
00:15:51,700 --> 00:15:54,620
style gotcha here right Russian
doll style
305
00:15:54,620 --> 00:15:57,620
Michael: what do you do you recommend
doing like just kicking
306
00:15:57,620 --> 00:16:00,540
off a bunch of queries analyzed
tape like per table
307
00:16:00,540 --> 00:16:04,380
Nikolay: I recommend partition
I recommend vacuumdb
308
00:16:04,800 --> 00:16:05,780
Michael: nice okay
309
00:16:05,920 --> 00:16:08,680
Nikolay: And speed up and go full
speed inside maintenance window.
310
00:16:08,680 --> 00:16:09,940
Again, it's a different story.
311
00:16:10,200 --> 00:16:15,780
But this vacuumdb, it has
--jobs
312
00:16:15,780 --> 00:16:17,120
or -j.
313
00:16:17,440 --> 00:16:18,300
You can define.
314
00:16:18,300 --> 00:16:22,240
And usually, we take as many courses
we have on the server and
315
00:16:22,240 --> 00:16:24,780
go full speed inside maintenance
window to achieve.
316
00:16:25,120 --> 00:16:28,200
Analyze should be quite fast if
you don't do vacuum.
317
00:16:29,160 --> 00:16:33,540
There is also gotcha a little bit
in vacuumdb options because
318
00:16:33,600 --> 00:16:37,320
vacuumdb's, --analyze
will also do vacuum.
319
00:16:37,580 --> 00:16:38,200
So there's
320
00:16:38,200 --> 00:16:39,860
Michael: also analyze only or
321
00:16:39,860 --> 00:16:41,140
Nikolay: there is analyze only.
322
00:16:41,240 --> 00:16:43,120
Yeah, but it's easy to overlook.
323
00:16:43,340 --> 00:16:45,800
There's 1 more gotcha here inside
all this.
324
00:16:46,300 --> 00:16:51,560
When people go with manual single-threaded
analyze or maybe multi-threaded
325
00:16:51,820 --> 00:16:54,120
but just explicit analyze.
326
00:16:55,080 --> 00:16:59,960
I've like quickly, it was interesting,
I was thinking someone
327
00:16:59,960 --> 00:17:01,560
said analyze can be super expensive.
328
00:17:01,560 --> 00:17:05,140
I agree, but even if it's like,
if the default_statistics_target
329
00:17:05,140 --> 00:17:06,780
is 1000, it's not that expensive.
330
00:17:06,780 --> 00:17:11,020
But back to this, can we throttle
it?
331
00:17:12,520 --> 00:17:16,100
For example, you want it to go
very slow, because autovacuum
332
00:17:16,100 --> 00:17:19,660
has autovacuum, doesn't have actually
333
00:17:19,660 --> 00:17:20,940
Michael: a vacuum_cost_delay also?
334
00:17:21,180 --> 00:17:24,060
Nikolay: Yes, there is
vacuum_cost_delay and vacuum_cost_limit.
335
00:17:25,360 --> 00:17:28,440
By default, it's off because I
think the cost limit is 0, meaning
336
00:17:28,440 --> 00:17:30,040
that it's not checked at all.
337
00:17:30,400 --> 00:17:33,720
Not cost limit, cost delay is 0,
like no check.
338
00:17:34,120 --> 00:17:38,820
But autovacuum has like mirrored
pair of these settings.
339
00:17:39,560 --> 00:17:40,460
It's throttled.
340
00:17:41,060 --> 00:17:43,520
Long story short, autovacuum is
throttled usually.
341
00:17:44,340 --> 00:17:47,440
And we actually usually fight with
our customers a little bit
342
00:17:47,440 --> 00:17:51,000
to increase this, make it even
more aggressive.
343
00:17:52,800 --> 00:17:56,040
And managed providers already did
part of that job, which is
344
00:17:56,040 --> 00:17:56,540
good.
345
00:17:56,880 --> 00:18:00,840
But if we run it manually, it's
not throttled.
346
00:18:00,840 --> 00:18:02,140
It will go full speed.
347
00:18:02,200 --> 00:18:06,960
I doubt you will need to throttle
it, but some people want, okay,
348
00:18:06,960 --> 00:18:08,040
let's throttle it.
349
00:18:08,100 --> 00:18:09,340
Question, how?
350
00:18:09,620 --> 00:18:14,440
We have a vacuum limit, vacuum_cost_limit, vacuum_cost_delay.
351
00:18:15,040 --> 00:18:19,060
We can set vacuum_cost_delay from default 0 to some point.
352
00:18:19,600 --> 00:18:23,320
But is it about Analyze, or it's only about vacuum?
353
00:18:23,320 --> 00:18:25,680
Based on just the naming, it's not about Analyze.
354
00:18:25,680 --> 00:18:27,040
It's about vacuum only.
355
00:18:28,140 --> 00:18:28,640
Michael: Right?
356
00:18:28,680 --> 00:18:29,900
Yeah, that would be my guess.
357
00:18:29,900 --> 00:18:33,780
But by the line of your questioning, I'm guessing it does affect
358
00:18:33,780 --> 00:18:34,620
your analysis.
359
00:18:34,820 --> 00:18:35,220
Nikolay: Right.
360
00:18:35,220 --> 00:18:39,620
I go to documentation and I see vacuum_cost_limit, vacuum_cost_delay,
361
00:18:39,620 --> 00:18:40,680
I think.
362
00:18:40,680 --> 00:18:41,740
And I see description.
363
00:18:41,980 --> 00:18:44,560
They talk only about vacuum, they don't talk about analysis.
364
00:18:45,040 --> 00:18:47,740
So I make conclusion, it's only about vacuum.
365
00:18:48,400 --> 00:18:53,560
But some part of my very long-term memory tells me, is it really
366
00:18:53,560 --> 00:18:54,060
so?
367
00:18:55,840 --> 00:18:59,540
And then Sadek Dusty, who helped me a lot with, and still helping
368
00:18:59,540 --> 00:19:03,240
sometimes when I write at how-to's and reviews How-To's, I'm
369
00:19:03,240 --> 00:19:06,060
very thankful for that.
370
00:19:06,880 --> 00:19:08,660
I have already 94 how-tos.
371
00:19:09,720 --> 00:19:11,660
So I wrote how-to, how-to Analyze.
372
00:19:11,930 --> 00:19:14,980
And right now I need to add this.
373
00:19:16,220 --> 00:19:19,140
vacuum_cost_limit, vacuum_cost_delay, they affect Analyze.
374
00:19:19,440 --> 00:19:23,680
If you scroll up to the beginning of section, you will see that
375
00:19:23,680 --> 00:19:26,340
it talks about both vacuum and Analyze.
376
00:19:26,800 --> 00:19:30,680
And we also, using AI, I checked source code and quickly found
377
00:19:30,680 --> 00:19:35,200
that there is a function called vacuumExec, which works with
378
00:19:35,200 --> 00:19:36,540
both vacuum and Analyze.
379
00:19:36,820 --> 00:19:40,040
And this confusion comes from source code, propagates to the
380
00:19:40,040 --> 00:19:42,480
documentation, and then to our heads, right?
381
00:19:42,560 --> 00:19:43,940
This is gotcha as well.
382
00:19:43,940 --> 00:19:47,460
So you can use vacuum_cost_limit, vacuum_cost_delay, to throttle
383
00:19:47,600 --> 00:19:51,300
Analyze, although I usually don't do it because I think we need
384
00:19:51,300 --> 00:19:52,320
to go full speed.
385
00:19:53,400 --> 00:19:55,900
Michael: And in the 1 example we're talking about here, we want
386
00:19:55,900 --> 00:19:57,280
to go faster, not slower.
387
00:19:57,660 --> 00:19:58,880
Nikolay: Right, right.
388
00:19:59,340 --> 00:20:00,560
But it's interesting, right?
389
00:20:00,660 --> 00:20:02,080
So there is some small confusion.
390
00:20:02,080 --> 00:20:04,060
I think there are many such confusions.
391
00:20:04,820 --> 00:20:06,540
But they are slowly fixed.
392
00:20:06,680 --> 00:20:08,400
They are slowly being fixed.
393
00:20:08,400 --> 00:20:10,860
Michael: Great example of 1 where the documentation
394
00:20:10,920 --> 00:20:13,760
wasn't helpful in avoiding that 1.
395
00:20:13,940 --> 00:20:14,780
So yeah, nice.
396
00:20:15,120 --> 00:20:17,960
I've got a few more beginner-friendly ones that maybe we could
397
00:20:17,960 --> 00:20:18,740
rattle through.
398
00:20:18,740 --> 00:20:23,560
I'm not even sure you'd consider them all gotchas, but 1 relates
399
00:20:27,620 --> 00:20:28,280
of places.
400
00:20:29,040 --> 00:20:30,900
I think that not only catches...
401
00:20:30,920 --> 00:20:32,660
Well, you don't think it's a gotcha?
402
00:20:33,120 --> 00:20:36,220
Nikolay: I think we should exclude
this on the same, like, we're
403
00:20:36,220 --> 00:20:41,540
using the same approach as now
because it's a huge bag of, yeah.
404
00:20:41,920 --> 00:20:42,320
Michael: Cool.
405
00:20:42,320 --> 00:20:45,080
And then another 1 that I see catch
out, well, a couple that
406
00:20:45,080 --> 00:20:48,280
I see catch out beginners, again,
maybe this is another huge
407
00:20:48,280 --> 00:20:53,400
topic, but access exclusive locks
on like just basically DDL
408
00:20:54,300 --> 00:20:58,080
blocking selects, like blocking
every, blocking inserts and like
409
00:20:58,080 --> 00:21:02,620
you know all sorts of people getting,
I think people don't realize
410
00:21:02,620 --> 00:21:05,680
because if they're working on small
databases at first, they
411
00:21:05,680 --> 00:21:09,860
start to grow in confidence of
how to do things.
412
00:21:10,080 --> 00:21:14,620
And then it only catches them out
once the startup's got really
413
00:21:14,620 --> 00:21:17,260
successful and the table's much
bigger, that kind of thing.
414
00:21:17,680 --> 00:21:23,080
Nikolay: Yeah, I think there is
some memes with Gauss distribution,
415
00:21:23,080 --> 00:21:24,500
or how it's called, right?
416
00:21:24,680 --> 00:21:25,660
Gaussian distribution.
417
00:21:25,760 --> 00:21:29,840
And first, I think schema changes
are painful.
418
00:21:31,300 --> 00:21:34,660
In the, like, schema changes are
super painful.
419
00:21:34,660 --> 00:21:36,920
They require expertise, like, beginner,
right?
420
00:21:37,040 --> 00:21:41,460
Then in the middle, you can imagine,
oh, Postgres has transactional
421
00:21:41,580 --> 00:21:44,720
DDL, everything is fine, we just
need to wrap everything into
422
00:21:44,720 --> 00:21:48,400
1 transaction and, and rely on
Postgres great capabilities of
423
00:21:48,400 --> 00:21:49,040
transactional DDL.
424
00:21:49,040 --> 00:21:50,860
Michael: Yeah, or just concurrently
and think
425
00:21:50,860 --> 00:21:53,400
Nikolay: yeah Yeah, MVCC works.
426
00:21:53,400 --> 00:21:56,680
Well, it doesn't block sell Excel
X are always working you can
427
00:21:56,680 --> 00:22:01,580
you can have a lot of Like exciting
stuff in the middle and then
428
00:22:01,580 --> 00:22:05,360
on the on the right you say post
this doesn't look was this has
429
00:22:05,360 --> 00:22:08,520
come Transactional detail, but
you cannot use it
430
00:22:09,040 --> 00:22:11,280
Michael: Well the in on the right
has to be the same as the left,
431
00:22:11,280 --> 00:22:11,720
doesn't it?
432
00:22:11,720 --> 00:22:13,040
Schema changes are painful.
433
00:22:13,380 --> 00:22:17,320
Nikolay: Yes, they are painful,
transactional DDL cannot be used
434
00:22:17,320 --> 00:22:24,380
in many, many cases, and you can
shoot your feet very well many
435
00:22:24,380 --> 00:22:24,880
times.
436
00:22:29,600 --> 00:22:31,120
So this is it, I think.
437
00:22:31,120 --> 00:22:32,940
And a lot of gotchas there.
438
00:22:33,740 --> 00:22:36,180
Michael: Another 1 that's not necessarily,
I'm not sure if this
439
00:22:36,180 --> 00:22:38,400
counts as a gotcha, I'd be interested
in your opinion but it
440
00:22:38,400 --> 00:22:41,780
does have seen it catch people
out and I guess it's a little
441
00:22:41,780 --> 00:22:45,340
bit of a foot gun and that's you
know you see the memes about
442
00:22:45,340 --> 00:22:48,620
this as well actually DELETE or
UPDATE without a WHERE clause
443
00:22:48,620 --> 00:22:52,000
and then just suddenly seeing you
know instead of 5 updated.
444
00:22:55,080 --> 00:22:57,720
But if you think like it's not
Postgres, why do you say it's
445
00:22:57,720 --> 00:22:59,120
not Postgres out of interest?
446
00:22:59,340 --> 00:23:02,360
Nikolay: Because the SQL standard
does it like defines this and
447
00:23:02,360 --> 00:23:06,540
any relational database which follows
SQL standard to some extent
448
00:23:07,120 --> 00:23:07,940
has it.
449
00:23:08,760 --> 00:23:09,260
Michael: Yeah.
450
00:23:10,140 --> 00:23:17,360
But I've seen clients catch these,
But the ones that ship, well,
451
00:23:17,360 --> 00:23:18,980
the only, the psql doesn't.
452
00:23:19,120 --> 00:23:22,480
So I don't think it's unreasonable
that Postgres does it this
453
00:23:22,480 --> 00:23:24,980
way, but I've definitely seen it
catch people out.
454
00:23:25,440 --> 00:23:26,100
Nikolay: I agree.
455
00:23:26,580 --> 00:23:27,880
Blame SQL standard.
456
00:23:28,140 --> 00:23:30,780
And there is extension to forbid
it.
457
00:23:30,780 --> 00:23:35,080
And also it was maybe 1 of the
very first hacking sessions with
458
00:23:35,080 --> 00:23:35,500
Andrei.
459
00:23:35,500 --> 00:23:43,000
We implemented some setting, GUC
setting in Postgres, which would
460
00:23:43,000 --> 00:23:48,820
allow administrators to, I don't
think error, warning, like completely
461
00:23:48,820 --> 00:23:50,380
forbid or just warn, I don't remember.
462
00:23:50,380 --> 00:23:52,220
I think error should be here.
463
00:23:52,540 --> 00:23:55,680
But it was not accepted, of course,
because I think it was discussed
464
00:23:55,680 --> 00:23:56,420
many times.
465
00:23:57,280 --> 00:23:58,480
I mean, it's possible.
466
00:23:58,940 --> 00:24:02,960
And right now, as I see, I think
PostgREST does it, right?
467
00:24:03,340 --> 00:24:03,840
PostgREST...
468
00:24:04,460 --> 00:24:05,440
Michael: Oh, does it?
469
00:24:05,640 --> 00:24:08,800
Nikolay: So usually right now it's
sold, if there is some middleware,
470
00:24:08,940 --> 00:24:09,840
it's sold there.
471
00:24:10,320 --> 00:24:15,220
So if you develop API using PostgREST,
for example, I think, Maybe
472
00:24:15,220 --> 00:24:17,220
I'm mistaken, but I think there
is a way.
473
00:24:17,320 --> 00:24:19,900
If there is no way, it's a good
idea to implement, actually.
474
00:24:19,900 --> 00:24:20,980
Michael: Yeah, it would be, yeah.
475
00:24:20,980 --> 00:24:26,820
Nikolay: Yeah, so if in URL of
your HTTP request of RESTful API,
476
00:24:27,080 --> 00:24:31,720
there is a command to run delete
without any filters, I think
477
00:24:31,720 --> 00:24:36,860
it will not do it it will not go
to progress with it so but inside
478
00:24:36,860 --> 00:24:42,380
database I don't I don't think
it's going to change right and
479
00:24:42,380 --> 00:24:44,080
we tried actually so
480
00:24:44,760 --> 00:24:48,060
Michael: yes with the well and
we tried what do you mean each
481
00:24:48,060 --> 00:24:49,120
right again
482
00:24:49,140 --> 00:24:51,900
Nikolay: we had a session yeah
we had a patch and they submitted
483
00:24:51,900 --> 00:24:56,240
it, but it was a small discussion
and chances are close to 0
484
00:24:56,240 --> 00:24:58,860
that it will be successful.
485
00:24:59,840 --> 00:25:02,060
Michael: Patch in psql or somewhere
else?
486
00:25:02,220 --> 00:25:03,340
Nikolay: No, not in psql.
487
00:25:03,580 --> 00:25:08,340
We wanted to have a Postgres
setting, GUC setting, to just
488
00:25:08,340 --> 00:25:12,840
allow administrators to forbid
unspecified, I don't remember
489
00:25:12,840 --> 00:25:16,500
how we called it, maybe unspecified
delete and update, when you
490
00:25:16,500 --> 00:25:19,020
don't have the WHERE clause at
all.
491
00:25:19,800 --> 00:25:21,120
Just like,
492
00:25:21,220 --> 00:25:21,720
Michael: cool,
493
00:25:22,060 --> 00:25:22,820
Nikolay: don't do it.
494
00:25:22,820 --> 00:25:26,260
There's a truncate for if you want
to hit right an update of
495
00:25:26,260 --> 00:25:30,900
whole table I don't know yeah but
again like right now it's in
496
00:25:30,900 --> 00:25:33,700
middleware usually sold in middle
where You can have triggers
497
00:25:33,700 --> 00:25:35,900
or something to protect yourself
if you want.
498
00:25:36,300 --> 00:25:38,960
Or this extension if you're on
self-managed Postgres.
499
00:25:38,960 --> 00:25:40,540
There is some extension for it.
500
00:25:40,760 --> 00:25:44,840
I wanted to mention 1 thing, step
back to DDL.
501
00:25:45,420 --> 00:25:51,000
My favorite example is, do you
think just adding a Column, you
502
00:25:51,000 --> 00:25:55,240
cannot put your traffic down or
your Database down?
503
00:25:55,240 --> 00:25:57,580
You can, if it cannot acquire Lock.
504
00:25:57,800 --> 00:26:01,660
It starts blocking all Queries
to this Table, even SELECTs.
505
00:26:02,580 --> 00:26:05,780
Like, I cannot acquire Lock, everyone
else can wait.
506
00:26:05,900 --> 00:26:11,540
Even SELECTs who come with access
Share Lock, don't touch this.
507
00:26:12,040 --> 00:26:12,760
That's it.
508
00:26:13,320 --> 00:26:14,340
And that's not good.
509
00:26:14,680 --> 00:26:17,660
And this is super unexpected and
a super big surprise.
510
00:26:18,720 --> 00:26:22,000
Michael: Yeah, especially because
you could even test that.
511
00:26:22,580 --> 00:26:27,620
You could even make a fork of production
or clone it run that
512
00:26:27,620 --> 00:26:31,520
on its own in isolation where there
is no Lock and it runs super
513
00:26:31,520 --> 00:26:35,540
fast so you think this is safe
but even though it was super fast
514
00:26:35,540 --> 00:26:39,720
it does require that heavy Lock
and that blocks everything else
515
00:26:39,720 --> 00:26:41,780
definitely a gotcha that's a great
1
516
00:26:41,800 --> 00:26:45,480
Nikolay: yeah yeah and there are
many others in the area of DDL
517
00:26:45,480 --> 00:26:51,600
but this I find like affecting
every single project which had
518
00:26:51,660 --> 00:26:55,900
like at least some growth like
I don't like to 1000 TPS and it's
519
00:26:55,900 --> 00:26:58,820
already noticeable it's not noticeable
in tiny projects
520
00:27:00,140 --> 00:27:02,900
Michael: yeah yeah which I think
is part is kind of part of the
521
00:27:02,900 --> 00:27:06,100
problem right or like at least
makes it worse because anybody
522
00:27:06,100 --> 00:27:10,920
that gains experience on smaller
projects as they grow Get some
523
00:27:10,920 --> 00:27:13,940
confidence that these things work
or they're fine and then it
524
00:27:13,940 --> 00:27:15,740
change changes at some point
525
00:27:16,320 --> 00:27:16,820
Nikolay: exactly
526
00:27:18,060 --> 00:27:20,140
Michael: so you've got a great
article in this actually I think
527
00:27:20,140 --> 00:27:24,900
that I can share about DDL it's
all about DDL changes I think
528
00:27:25,160 --> 00:27:28,860
Nikolay: yeah it's yeah yeah it's
this this 1 is definitely included
529
00:27:28,860 --> 00:27:33,180
I think this 1 like has a different
blog post about like I have
530
00:27:33,180 --> 00:27:37,980
few about Details okay what else
531
00:27:38,760 --> 00:27:41,720
Michael: well in that in that area
of making big changes partly
532
00:27:41,720 --> 00:27:45,200
by mistake you know that the DELETE
or UPDATE without WHERE Do
533
00:27:45,200 --> 00:27:48,660
you think people would expect to
be able to undo something?
534
00:27:48,940 --> 00:27:54,440
I'm not thinking just from people
with experience of relational
535
00:27:54,440 --> 00:27:58,520
databases, but the fact that if
you do something like that by
536
00:27:58,520 --> 00:28:02,080
mistake, that you have to go to
your backups to get that data
537
00:28:02,080 --> 00:28:02,580
back.
538
00:28:03,080 --> 00:28:06,260
If I was in my early 20s or just
out, you know, if I was in my
539
00:28:06,260 --> 00:28:10,120
teens, all other software I use
has the ability to undo something
540
00:28:10,120 --> 00:28:11,420
if I do it by mistake.
541
00:28:11,940 --> 00:28:16,220
So it does feel slightly unexpected,
potentially if I've grown
542
00:28:16,220 --> 00:28:19,640
up in that world, that I can make
1 mistake and not be able to
543
00:28:19,640 --> 00:28:19,960
undo it.
544
00:28:19,960 --> 00:28:21,220
Nikolay: And what Database you
can?
545
00:28:21,220 --> 00:28:22,440
I mean, of course, there are like...
546
00:28:22,440 --> 00:28:23,440
Michael: Yeah, I don't know.
547
00:28:23,440 --> 00:28:24,660
Nikolay: Time travel or...
548
00:28:25,840 --> 00:28:27,500
If branching is supported, you
can...
549
00:28:27,500 --> 00:28:32,140
But it's still like not super simple, right?
550
00:28:32,520 --> 00:28:33,720
Well, yeah, I don't know.
551
00:28:33,720 --> 00:28:36,800
I mean, there are several projects which try to solve this problem
552
00:28:36,820 --> 00:28:41,760
and I mean the data specific databases supporting branching for
553
00:28:41,760 --> 00:28:47,620
example or even other I think Have you heard about this new company
554
00:28:47,660 --> 00:28:49,520
where Michael Stonebraker is participating?
555
00:28:50,920 --> 00:28:51,060
Michael: I've
556
00:28:51,060 --> 00:28:53,000
heard of it, I don't know much about it.
557
00:28:53,000 --> 00:28:53,500
Nikolay: DBOps?
558
00:28:53,840 --> 00:28:54,840
Or how is it called?
559
00:28:54,840 --> 00:28:55,700
I don't remember.
560
00:28:55,920 --> 00:28:57,100
Not DBOps, DBOS.
561
00:28:58,700 --> 00:28:59,200
Michael: Yes.
562
00:29:00,180 --> 00:29:03,160
Nikolay: So I wonder if this feature will be inside it.
563
00:29:03,860 --> 00:29:04,700
I don't know.
564
00:29:04,740 --> 00:29:06,260
For me, it's not expected.
565
00:29:06,380 --> 00:29:12,100
I cannot name this gotcha because it's a hard problem, and we
566
00:29:13,140 --> 00:29:18,820
didn't get used to it, to having it, because it's rare.
567
00:29:19,710 --> 00:29:28,100
But if we go to young people's minds, there are many gotchas
568
00:29:28,100 --> 00:29:28,780
for them, right?
569
00:29:28,780 --> 00:29:30,700
Oh, this is working not as I expected.
570
00:29:32,080 --> 00:29:36,360
So naming is hard just because it should avoid gotchas.
571
00:29:36,380 --> 00:29:40,480
If you chose some name, you should think about other people and
572
00:29:40,480 --> 00:29:42,180
think to be very predictable.
573
00:29:42,980 --> 00:29:44,840
This is the art of naming.
574
00:29:45,440 --> 00:29:49,200
And we just discussed this vacuum_cost_limit affecting analyze.
575
00:29:50,140 --> 00:29:56,280
So yeah, and in young minds, gotchas, because gotchas world is
576
00:29:56,280 --> 00:30:00,740
much bigger because they don't understand the logic in many places,
577
00:30:00,740 --> 00:30:05,740
how it's like, like common practice in many places, right?
578
00:30:05,740 --> 00:30:08,540
And that's why many more unexpected situations.
579
00:30:09,640 --> 00:30:10,460
Michael: Yeah, fair.
580
00:30:11,000 --> 00:30:14,540
Nikolay: Yeah, by the way, if you run pg_dump on a very large
581
00:30:14,880 --> 00:30:21,400
database, like 1 table after another, And then we deal with snapshot,
582
00:30:21,400 --> 00:30:21,900
right?
583
00:30:22,580 --> 00:30:26,700
With snapshot, it's a repeatable read and snapshot.
584
00:30:26,820 --> 00:30:32,000
And even if you use multiple workers for pg_dump, they are synchronized
585
00:30:32,360 --> 00:30:33,780
reading from the same snapshot.
586
00:30:34,200 --> 00:30:38,100
But what if some table is dropped?
587
00:30:38,360 --> 00:30:40,340
Will it be present in this table?
588
00:30:41,040 --> 00:30:42,180
I'm not sure, actually.
589
00:30:42,880 --> 00:30:44,340
I just think there is a God check
590
00:30:44,340 --> 00:30:44,840
Michael: here.
591
00:30:45,660 --> 00:30:51,300
Nikolay: If during dump there are some schema changes, can we
592
00:30:51,300 --> 00:30:54,240
have some inconsistency in backups?
593
00:30:55,260 --> 00:30:56,580
Not in backups, in dumps.
594
00:30:56,580 --> 00:31:01,160
By the way, this confusion was resolved recently, right?
595
00:31:01,220 --> 00:31:06,040
We didn't mention it in the previous discussions of confusions,
596
00:31:06,060 --> 00:31:15,520
but the pg_dump page is not saying it's for dumps anymore.
597
00:31:15,940 --> 00:31:17,380
So dumps are not backups.
598
00:31:19,660 --> 00:31:20,880
Michael: That's coming.
599
00:31:21,960 --> 00:31:22,960
Nikolay: Yeah, in 2018.
600
00:31:23,100 --> 00:31:23,940
Okay, okay, okay.
601
00:31:23,940 --> 00:31:25,300
We will discuss this additionally.
602
00:31:25,640 --> 00:31:29,940
But this is a big confusion when
the computation says pg_dump
603
00:31:30,060 --> 00:31:31,080
is a backup tool.
604
00:31:31,080 --> 00:31:33,220
It's still so, even in 16.
605
00:31:33,760 --> 00:31:38,660
And now we have all rights to say
it's like all people who said
606
00:31:38,800 --> 00:31:42,500
pg_dump is not a backup tool, we
are right, because finally in
607
00:31:42,500 --> 00:31:44,040
18 it's already changed.
608
00:31:44,040 --> 00:31:47,340
I think it won't be reverted, I
hope so, this patch.
609
00:31:49,540 --> 00:31:54,800
But back to our topic, pg_dump can
be expected to be a tool for
610
00:31:54,800 --> 00:31:56,460
backups just because of documentation.
611
00:31:56,720 --> 00:32:01,320
Then you have quite a painful process
of realizing it's very
612
00:32:01,320 --> 00:32:02,320
bad for backups.
613
00:32:02,900 --> 00:32:06,600
So it's a gotcha, which is already
fixed in the future in Postgres
614
00:32:07,000 --> 00:32:07,500
18.
615
00:32:09,860 --> 00:32:18,900
And if we, in this area, pg_restore
doesn't run analyze, which
616
00:32:19,160 --> 00:32:24,620
hurts every second attempt to restore
a big database, even with
617
00:32:24,620 --> 00:32:26,620
experienced people like I am.
618
00:32:26,880 --> 00:32:29,920
Because, again, it's like with
pg_upgrade, we discussed it.
619
00:32:29,920 --> 00:32:33,400
pg_restore, You restore a huge
dump, you start working with
620
00:32:33,400 --> 00:32:38,940
it, but it's slow, and in plans
you see where you expect a simple
621
00:32:38,940 --> 00:32:42,520
index scan, you see bitmap scans,
bitmap index, bitmap heap scan,
622
00:32:42,520 --> 00:32:44,720
because there is no vacuum, there
is no analysis.
623
00:32:45,060 --> 00:32:50,580
It also should run on a vacuum
to collect visibility maps.
624
00:32:51,340 --> 00:32:51,840
Or
625
00:32:53,300 --> 00:32:56,980
Michael: it might not be unreasonable
to think that maybe backups
626
00:32:56,980 --> 00:32:59,980
would include the statistics and
then restore would restore the
627
00:32:59,980 --> 00:33:00,480
statistics.
628
00:33:01,400 --> 00:33:02,920
Nikolay: Physical backups, I agree.
629
00:33:03,280 --> 00:33:04,860
Logical backups, I disagree.
630
00:33:06,680 --> 00:33:10,260
You don't include indexes, which
is derivative from data itself.
631
00:33:10,260 --> 00:33:12,840
Statistics is also derivative of
data.
632
00:33:13,660 --> 00:33:16,120
So you include description, like
create index.
633
00:33:16,320 --> 00:33:20,520
There should be, maybe should be
some word like analyze in there.
634
00:33:22,060 --> 00:33:25,620
I wanted to say create statistics,
but it was analyzed already.
635
00:33:26,180 --> 00:33:27,100
There's such word.
636
00:33:27,500 --> 00:33:28,200
Why restore?
637
00:33:28,200 --> 00:33:31,420
And restore could run it.
638
00:33:31,420 --> 00:33:37,280
If we use pg_restore -j
8, for example, 8 parallel drops.
639
00:33:37,920 --> 00:33:43,160
In this case, why are we not recalculating
statistics?
640
00:33:44,100 --> 00:33:48,720
Right now, everyone who deals with
some automation, for example,
641
00:33:48,720 --> 00:33:52,200
for DBLab Engine, we need it when
provisioning is logical.
642
00:33:52,200 --> 00:33:55,440
So it's dump restore and we need
to move as fast as possible
643
00:33:55,440 --> 00:34:00,180
multiple jobs, multiple workers
for dump, multiple workers for
644
00:34:00,180 --> 00:34:00,680
restore.
645
00:34:01,100 --> 00:34:05,920
And then of course, vacuumdb,
in this case, --analyze
646
00:34:05,920 --> 00:34:10,840
to have vacuum as well and also
-j, but People forget about
647
00:34:10,840 --> 00:34:14,340
this and forget forgetting means
like you expect it will be fine,
648
00:34:14,340 --> 00:34:20,220
but if you don't run analyze yourself
ideally in multiple threads
649
00:34:20,220 --> 00:34:23,400
and multiple workers using multiple
workers in this case performance
650
00:34:23,400 --> 00:34:28,200
will be very bad and people start
thinking oh Postgres is slow
651
00:34:30,040 --> 00:34:33,540
have you heard about this Like
I restore from dump and it's slow.
652
00:34:35,140 --> 00:34:39,400
Michael: I have to admit I haven't
heard that complaint, no.
653
00:34:40,860 --> 00:34:46,240
Nikolay: Okay, I'm hearing it and
I'm doing it myself almost
654
00:34:46,240 --> 00:34:47,060
20 years.
655
00:34:47,088 --> 00:34:49,172
I know about this.
656
00:34:49,200 --> 00:34:51,500
Michael: No, I'm not saying it
doesn't exist, I just haven't,
657
00:34:51,500 --> 00:34:54,880
you know, maybe it's just not the
category of problem maybe what
658
00:34:54,880 --> 00:34:58,940
happens when people experience
that is they don't noticed online
659
00:34:59,380 --> 00:35:02,860
or I didn't know it's or they don't
post they just go try something
660
00:35:02,860 --> 00:35:03,360
else
661
00:35:03,520 --> 00:35:07,120
Nikolay: yeah it's it's not a big
deal if you restore, and it's
662
00:35:07,120 --> 00:35:10,760
working, and then you want to deal
with it 1 day later.
663
00:35:10,760 --> 00:35:14,120
Because probably, likely, autovacuum
will do it.
664
00:35:14,600 --> 00:35:18,620
But If you expect to run fast queries
immediately after restoration
665
00:35:18,920 --> 00:35:24,000
from a dump, I'm talking about
something which is 100% very well
666
00:35:24,000 --> 00:35:27,940
known to everyone, who is at least
a little bit experienced.
667
00:35:28,700 --> 00:35:32,000
But it doesn't make it non-gotcha,
it's still gotcha.
668
00:35:34,360 --> 00:35:39,440
That pg_restore doesn't calculate
statistics and doesn't run Vacuum.
669
00:35:42,040 --> 00:35:44,620
Michael: I mean it's quite remarkable,
I know we could go on
670
00:35:44,620 --> 00:35:47,960
with this list for quite a while
and there's like varying levels
671
00:35:47,960 --> 00:35:53,000
of gotchas but I like that I like
the list you sent me how how
672
00:35:53,000 --> 00:35:57,840
short and brief it is and I I really
think for many other databases
673
00:35:58,320 --> 00:36:02,760
it would be a much much longer
list I listened to well you're
674
00:36:02,760 --> 00:36:06,260
listening to your experience of
you know a couple of days of
675
00:36:06,260 --> 00:36:10,840
trying to use MySQL at the beginning,
and recently I was listening
676
00:36:10,840 --> 00:36:14,820
to an interview with Tom Lane,
and he mentioned, like, checking
677
00:36:14,820 --> 00:36:19,540
out MySQL at the beginning and
not liking a few things about
678
00:36:19,540 --> 00:36:19,940
it.
679
00:36:19,940 --> 00:36:22,100
And that feels like a really common
experience.
680
00:36:22,540 --> 00:36:25,920
And having worked with commercial
databases like SQL Server and
681
00:36:25,920 --> 00:36:32,080
Oracle, that often move much faster
in terms of adding features
682
00:36:32,080 --> 00:36:33,940
that enterprise clients really
want.
683
00:36:34,120 --> 00:36:39,240
There's just so many more gotchas
that result from processes
684
00:36:39,360 --> 00:36:39,800
like that.
685
00:36:39,800 --> 00:36:41,120
So I imagine I could be wrong.
686
00:36:41,120 --> 00:36:44,620
Nikolay: I think Postgres has lots
of gotchas, lots of them.
687
00:36:45,300 --> 00:36:47,580
Michael: But compared to other
relational databases?
688
00:36:48,340 --> 00:36:51,360
Nikolay: Yeah, it's a complex system,
all complex systems have
689
00:36:51,360 --> 00:36:52,280
a lot of gotchas.
690
00:36:52,600 --> 00:36:57,920
Some of them are just very niche,
very narrow and deep and so
691
00:36:57,920 --> 00:36:58,420
on.
692
00:36:58,940 --> 00:37:01,760
Some of them are like nobody knows
about them.
693
00:37:01,760 --> 00:37:04,900
For example, SELECT INTO.
694
00:37:06,820 --> 00:37:09,740
This is what you can write inside
PL/pgSQL, right?
695
00:37:10,080 --> 00:37:15,140
So you write a FUNCTION or TRIGGER,
and you write SELECT INTO
696
00:37:15,300 --> 00:37:17,560
some variable, blah, blah, blah.
697
00:37:17,560 --> 00:37:20,860
And then you think, OK, this SELECT
is like maybe it's complex
698
00:37:20,860 --> 00:37:21,760
SELECT, actually.
699
00:37:22,380 --> 00:37:26,040
Subselect or, I don't know, joins
and so on.
700
00:37:26,040 --> 00:37:29,360
But in the end, you have a scalar
or something, and you select
701
00:37:29,600 --> 00:37:31,680
into a variable inside PL/pgSQL.
702
00:37:31,800 --> 00:37:34,240
And then you think, I want to understand
the plan, or I want
703
00:37:34,240 --> 00:37:38,940
to just run it and try to troubleshoot,
and you put it to psql,
704
00:37:39,840 --> 00:37:40,840
what will happen?
705
00:37:40,840 --> 00:37:45,860
If you put SELECT INTO blah blah
blah, and then some regular
706
00:37:45,920 --> 00:37:49,380
select from where order by you
know
707
00:37:49,380 --> 00:37:52,620
Michael: just an error no what
happens
708
00:37:52,900 --> 00:37:54,240
Nikolay: it will create a table
709
00:37:56,120 --> 00:37:57,120
Michael: oh okay yeah
710
00:37:57,120 --> 00:38:01,360
Nikolay: go select into is 1 of
your lights it's great table
711
00:38:02,420 --> 00:38:06,140
This I think just should be removed,
like completely removed,
712
00:38:06,380 --> 00:38:06,880
deprecated.
713
00:38:07,900 --> 00:38:10,300
Select into creating a table, it's
a DDL.
714
00:38:15,140 --> 00:38:17,580
This is definitely a gotcha for
everyone.
715
00:38:18,840 --> 00:38:21,540
Michael: Yes, imagine all those
parsers that just...
716
00:38:21,820 --> 00:38:25,240
I know this is flawed for multiple
reasons, but look at any query
717
00:38:25,240 --> 00:38:28,140
that starts with SELECT, and like,
oh, it's a read query.
718
00:38:28,200 --> 00:38:32,780
Nikolay: Well, yeah, usually we
say SELECT for update is acquiring
719
00:38:32,860 --> 00:38:35,280
a heavy lock, blocking all writes.
720
00:38:36,220 --> 00:38:42,300
Yes, blocking all writes on these
rows, particular rows, not
721
00:38:42,380 --> 00:38:43,280
the whole table.
722
00:38:43,620 --> 00:38:46,780
But Select can create a table.
723
00:38:47,180 --> 00:38:49,700
And we have create table as select
already.
724
00:38:49,840 --> 00:38:53,180
And this is what all people use,
I think, who need it.
725
00:38:53,600 --> 00:38:59,440
So select into probably just some
very old stuff that could be
726
00:38:59,440 --> 00:39:01,080
potentially removed, I think.
727
00:39:01,400 --> 00:39:03,280
Michael: If it's not in the SQL
standard
728
00:39:05,200 --> 00:39:09,560
Nikolay: oh it's a good point if
it is no chances right
729
00:39:09,780 --> 00:39:13,700
Michael: yeah well probably not
no cool anything else you want
730
00:39:13,700 --> 00:39:14,840
to make sure we covered
731
00:39:15,420 --> 00:39:18,480
Nikolay: maybe it's enough I think
we covered less than 1% of
732
00:39:18,480 --> 00:39:19,620
what we could.
733
00:39:19,700 --> 00:39:20,740
This is my feeling.
734
00:39:20,740 --> 00:39:21,640
What do you think?
735
00:39:22,240 --> 00:39:25,560
Michael: Well, it depends what
you count as gotchas and how niche
736
00:39:25,560 --> 00:39:26,640
you're willing to go.
737
00:39:26,640 --> 00:39:29,640
It turns out the more you know,
the more gotchas you know about,
738
00:39:29,640 --> 00:39:30,280
I guess.
739
00:39:31,220 --> 00:39:34,100
Nikolay: So I could not resist
and I checked the documentation.
740
00:39:34,640 --> 00:39:37,940
SQL standard uses SELECT INTO to
represent selecting values into
741
00:39:37,940 --> 00:39:43,380
a scalar variable of a host program
rather than creating a new
742
00:39:43,380 --> 00:39:43,700
table.
743
00:39:43,700 --> 00:39:47,220
It's definitely Postgresism and
I think it should be removed.
744
00:39:47,720 --> 00:39:49,340
Michael: Okay, cool, good 1.
745
00:39:50,500 --> 00:39:53,220
Nikolay: Good, okay, good chat,
maybe some kind of entertaining
746
00:39:53,240 --> 00:39:56,100
more than useful, but I enjoyed
it.
747
00:39:56,100 --> 00:39:56,820
I enjoyed it.
748
00:39:56,820 --> 00:39:57,540
Michael: Yeah, absolutely.
749
00:39:58,320 --> 00:40:02,660
And feel free to send us any more
that you've got or that you
750
00:40:02,660 --> 00:40:05,900
Nikolay: Maybe we should think
about specific areas like we did
751
00:40:05,900 --> 00:40:11,740
for for now and maybe we should
explore some areas from this
752
00:40:11,740 --> 00:40:13,320
perspective what can be unexpected
753
00:40:14,340 --> 00:40:16,680
Michael: Yeah, for sure. Thanks
so much.
754
00:40:16,680 --> 00:40:17,220
Nikolay.
755
00:40:17,220 --> 00:40:18,180
Catch you next week.
756
00:40:18,180 --> 00:40:18,240
Nikolay: Thank you.
757
00:40:18,240 --> 00:40:18,560
You too.