概述
上一篇文章《PostgreSQL逻辑复制槽的备份和还原》中提到:使用copy导出二进制文件时,文件头增加了25字节,文件尾增加了2字节,当时并没有深入探究这两个数字是怎么来的,只是验证了不同版本都保持同样的现象。
今天又翻看了一下源码,结果如下图所示(Int32占4个字节,Int16占2个字节)

其中,文件头长度=11+8+2+4=25,文件尾长度=2
根据“PGCOPY”搜索,在源码backend/commands/copyto.c中,可以找到每一部分的含义
详解
首先定义了一个由11个字节构成的字符
static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0";
文件头
/*
* Copy from relation or query TO file.
*/
uint64
DoCopyTo(CopyToState cstate)
......
if (cstate->opts.binary)
{
/* Generate header for a binary copy */
int32 tmp;
/* Signature */
CopySendData(cstate, BinarySignature, 11); #11字节常量
/* Flags field */
tmp = 0;
CopySendInt32(cstate, tmp); #4字节
/* No header extension */
tmp = 0;
CopySendInt32(cstate, tmp); #4字节
}
/*
* Emit one row during DoCopyTo().
*/
static void
CopyOneRowTo(CopyToState cstate, TupleTableSlot *slot)
......
if (cstate->opts.binary)
{
/* Binary per-tuple header */
CopySendInt16(cstate, list_length(cstate->attnumlist)); #2字节,字段个数
......
if (!cstate->opts.binary)
......
else
{
bytea *outputbytes;
outputbytes = SendFunctionCall(&out_functions[attnum - 1],
value);
CopySendInt32(cstate, VARSIZE(outputbytes) - VARHDRSZ); #4字节,数据大小
CopySendData(cstate, VARDATA(outputbytes),
VARSIZE(outputbytes) - VARHDRSZ); #数据内容
文件尾
if (cstate->opts.binary)
{
/* Generate trailer for a binary copy */
CopySendInt16(cstate, -1); #2字节,文件结尾
/* Need to flush out the trailer */
CopySendEndOfRow(cstate);
}
至此,我们知道了使用copy导出二进制文件时,文件头(25个字节)和文件尾(2个字节)这两个数字的来源。
最后修改时间:2024-04-20 19:51:33
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




