如何实现PostgreSQL对某一张表的WAL日志进行记录

【PostgreSQL逻辑复制数据同步到kafka】 目前CDC(Change Data Capture)工具还是比较多的 ,现在有部分增量数据同步工具是基于触发器实现的,把数据库的变化记录到某个系统表中,然后在客户端建立缓冲,并定期将变化push到接收端,接收端和发送端建立通道,并定期pull新的数据变化,在目标数据库回放 。但因为使用了触发器会影响生产环境的性能,这点可能无法接受 ,其他的增量数据同步工具中占比比较大的一类,是基于kafka来实现的。例如RedHat开源的 Debezium。通过抽取数据库日志来获取变更,实现增量数据同步。下面是一个Post 阅读详情

PostgreSQL 没有内置的 binlog(binary log)机制像 MySQL 那样。它使用 Write-Ahead Logging (WAL) 来记录数据库的变更。要将这些变更记录到某张表中,通常可以使用逻辑复制(Logical Replication)和触发器(Triggers)来实现。以下是一个实现的思路:

1. 启用逻辑复制

首先,确保 PostgreSQL 已启用逻辑复制:
在 postgresql.conf 文件中,设置以下参数:

# 启用逻辑复制
wal_level = logical

# 设置允许的最大同步槽数量
max_replication_slots = 4

# 设置允许的最大订阅数量
max_wal_senders = 4

然后重启 PostgreSQL 服务:

sudo systemctl restart postgresql

2. 创建发布和订阅

1. 创建发布

在数据库中,创建一个发布:

CREATE PUBLICATION my_publication FOR TABLE my_table;

这样,my_table 的变更将会被记录并可以被订阅。

2. 创建订阅

在另一个数据库中,创建一个订阅:

CREATE SUBSCRIPTION my_subscription
CONNECTION 'dbname=mydb host=localhost user=myuser password=mypassword'
PUBLICATION my_publication;

这样,my_table 的变更将会被传输到本地的订阅数据库。

3. 使用触发器记录变更

如果你希望将变更记录到特定的表中,你可以创建触发器。以下是一个简单的示例:

  1. 创建日志表
CREATE TABLE my_table_log (
    id SERIAL PRIMARY KEY,
    operation TEXT,
    old_data JSONB,
    new_data JSONB,
    changed_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);
  1. 创建触发器函数
CREATE OR REPLACE FUNCTION log_my_table_changes() RETURNS TRIGGER AS $$
BEGIN
    INSERT INTO my_table_log (operation, old_data, new_data)
    VALUES (
        TG_OP,
        row_to_json(OLD),
        row_to_json(NEW)
    );
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
  1. 创建触发器
CREATE TRIGGER my_table_changes
AFTER INSERT OR UPDATE OR DELETE ON my_table
FOR EACH ROW
EXECUTE FUNCTION log_my_table_changes();

这样,每当 my_table 表中的数据发生变化时,触发器会将这些变更记录到 my_table_log 表中。这种方法可以记录数据库表中的变更并进行审计。

Oracle/MySQL/PostgreSQL的MVCC实现及redo/undo/binlog相关概念 最近好像突然有点回归到传统的关系型/集中式数据库原理上面来了,也可能是之前一直对这些概念印象不太深刻。今天再总结一下,好让记忆深刻一些。本文主要的目的是把Oracle、MySQL、PostgreSQL三大主流的关系型数据库中关于MVCC实现及redo log、undo log及binlog的关系描述清楚。 阅读详情

相关推荐

Postgresql wal日志

wal日志wal日志是什么WAL机制实现LSN标记pg的wal配置检查点 wal日志是什么 WAL即Write-Ahead Logging,预写式日志(WAL)是保证数据完整性的一种标准方法。WAL的中心概念是数据文件(存储着表和索引)的修改必须在这些动作被日志记录之后才被写入,即在描述这些改变的日志记录被刷到持久存储以后。如果我们遵循这种过程,我们不需要在每个事务提交时刷写数据页面到磁盘,因为...

以前冷现在热 6796

postgresql 的三种日志

最近在模拟主备切换,备机可以成功切换成主机,但是主机未成功切换成备机,翻阅资料后发现是日志归档设置的问题。 情景描述:主从复制,模拟主机当掉,主从切换。从机成功切换为主机,但主机切换为从机后服务无法启动,查看日志后,报如下错误: ERROR:  requested WAL segment 000000020000000000000030 has already been removed

lanonola的专栏 3万+

WAL日志

PG WAL(Write-Ahead Logging)日志是PostgreSQL数据库中的一种重要机制,用于保证数据库的完整性和数据恢复。WAL日志是PostgreSQL的持久性技术,它将所有对数据库的修改操作(如INSERT、UPDATE、DELETE等)记录到一个称为WAL日志的文件中。这些记录是在对数据库中的数据进行任何修改之前进行的,即“先记后做”。这种机制确保了即使系统崩溃或发生意外停机,也可以使用WAL日志来恢复数据库的一致性状态。

qiao2458的博客 2094

postgresql|数据库|插件学习(一)---postgresql-12的内置插件pg_stat_statements的启用和使用

插件就是原软件的扩展功能。postgresql有非常多的各种各样的插件,当然了,插件不安装对于我们使用数据库并没有什么太多的影响,可能只是不舒服一些而已,但有一些插件我们如果有安装,那么,对于数据库的维护,管理工作可能会更加的方便,快捷,pg_stat_statements这个插件就是这样的一个插件,概括起来,这个插件的功能就是提供postgresql监控的,提供了一种跟踪执行的所有SQL语句的统计信息的方法。 这里多说一句,不像MySQL,开启binlog日志就可以统计慢

zsk_john的技术分享专用博客 3306

《postgresql指南--内幕探索》第九章 预写式日志(WAL)

事务日志是数据库的重要组成部分,存储了数据库系统中所有更改和操作的历史,以确保数据库不会因为故障(例如掉电或其他导致服务器崩溃的故障)而丢失数据。在PostgreSQL(以下简称PG)中,事务日志文件称为Write Ahead Log(以下简称WAL)。 使用WAL不仅可以保证数据库事务操作的持久性,也可以显著地减少写磁盘的次数,因为只需要把日志文件刷新到磁盘就可以保证事务被提交,而不需要把事务改动过的每一个数据文件都刷新到磁盘。日志文件是连续写的,所以同步log的花销远小于刷新数据页的花销。特别是服务器要

hmxz2nn的博客 2982

PostgreSQL:WAL日志归档策略

文章目录概述参数配置归档策略脚本 概述 今天分享一个PostgreSQL数据库配置wal日志归档的策略。所谓wal日志归档,就是把在线的wal日志备份出来。说起来简单,但是在正式的系统上需要一个完备的归档策略,以备系统所需稳定 参数配置 在开启wal日志归档,首先需要设置几个参数 wal_level = replica 该参数的可选的值有minimal,replica和logical,wal的...

高云平的博客 5076

PostgreSQL(十一)WAL日志管理

PG的WAL(Write Ahead Log)日志,意为 预写式日志,特点是先记后做。例如:假设发生一个update事务,数据库的操作步骤:(1)将update事务转化为特定格式,形成日志条目,记录至内存中的wal buffer;(2)从磁盘的数据文件中读取需要update的数据至内存中的buffer cache,然后进行update,得到脏块;(3)commit这个事务(或满足其他触发条件),wal writer进程将wal buffer中日志条目记录至磁盘的wal文件中;

shmily_coco的博客 3950

oracle的redo与postgreSQL的WAL以及MySQL的binlog区别

MySQL的binlog是一种用于记录数据库变更操作的事务日志。它可以用于数据恢复、增量备份和数据同步等场景。binlog有不同的记录格式可供选择,且需要配置和管理相关参数来控制其行为和保留策略。

Auspicious航的博客 2308

postgresql的pg_wal日志

个人整理,来源: https://developer.aliyun.com/article/694169 https://www.cnblogs.com/VicLiu/p/11854782.html https://blog.youkuaiyun.com/weixin_39540651/article/details/105737136 https://www.cnblogs.com/VicLiu/p/11854782.html 网络上还存在大量的帖子,关于pg_log,xlog,clog 刚刚接触PG.

Aiky哇 8650

Java与PostgreSQL基于WAL的日志实时数据同步技术实现

WAL(Write-Ahead Logging,预写式日志)是关系型数据库中用于保证数据一致性和持久性的一种重要机制。在事务处理中,WAL的作用是确保所有数据变更记录在日志文件中之后,才能真正地修改数据库文件。这个过程遵循ACID原则中的原子性和持久性,从而防止事务过程中发生系统崩溃导致的数据丢失。WAL日志的配置涉及多个参数,这些参数定义了WAL的行为和性能特性。以下是几个核心的配置参数:wal_level:用于指定WAL日志的详细级别,有minimalreplica和logical。

weixin_35578748的博客 860

ISP图像处理Verilog仿真框架搭建(附代码)

基于Verilog的图像处理仿真框架搭建

路漫漫其修远兮,吾将上下而求索 1898

【技术实现】java实时同步postgresql变更数据,基于WAL日志

java基于WAL日志订阅获取postgresql实时变更数据,类属于阿里巴巴的canal数据同步工具,基于postgresql jdbc的PGReplicationStream实现,涉及postgresql数据库的逻辑复制、订阅与通知

dylan的博客 6149

FICO F.27 Customer statement 打印

需求,定制化打印,替换标准的F.27打印 类似于采购订单的打印,但是略有不同,查阅资料之后步骤如下: T-code F.27 is SAP standard program to produce customer/vendor correspondence (letter). Correspondence Type is used to specify the related printing program and form for the particular correspondence. SAP

IamRunjiang的博客 1965

PostgreSQL 待归档 WAL 日志告警分析

告警名称: PostgreSQL 待归档 WAL 日志告警。

喝醉酒的小白 1394

STM32实战:5分钟搞定MXL90614红外测温模块的I2C驱动(附完整代码)

本文提供了一份快速集成MLX90614红外测温模块的STM32实战指南。通过详细的软件I2C驱动代码,重点解析了SMBus通信协议、CRC校验及温度数据转换,帮助开发者避开常见陷阱,实现5分钟内完成模块驱动并读取准确温度值。

wasm7browser的博客 353

使用运放构建电压跟随器

运放,是运算放大器的简称 运算放大器是用模拟电子器件(如晶体管,场效应管,二极管等)构成的模拟集成电路,其特点是有很高的放大倍数和抗干扰能力,因此可以被设计成各种用途的派生电路,如电压比较器、窗口电路、波形发生电路等等,其中也有电压跟随器。 电压跟随器是一种具有100%电压负反馈的放大器电路,其特点是输出电压的幅度和极性都与输入电压相同,所以叫跟随器。典型线路如图所示: 运放跟随器有输入阻抗高,而输出阻抗低的特性,一般来说,输入阻抗可以达到几兆欧姆,而输出阻抗低,通常只有几欧姆,甚至更低。 在电

Code for Coffee 5万+

PostgreSQL WAL 日志分析报告

基本查看# 统计记录类型# 统计操作类型# 查找特定表的操作索引是 WAL 生成的主要来源- 占总量的 64%GIN 索引开销最大- 单独占 24%每个索引都会乘数级增加 WAL- 5 个索引 = 6 倍 WALpg_waldump 是定位 WAL 问题的利器- 可精确分析操作来源wal_compression 是最简单的优化手段- 可立即减少 30-50% WAL 大小报告生成时间: 2025-12-26分析工具: pg_waldump (PostgreSQL 15.7)

喝醉酒的小白 1052

深度解析中国支付清算体系

说起国之重器,不仅仅有 东风快递、渔16、渔17、渔18,还有另外一个国之重器-CNAPS2(中国支付清算体系)。 中国国内支付行业的发达水平、繁荣程度,不客气的讲,在全世界都是数一数二的,世界上最大的银行卡组织银联在中国,世界上交易量最大的网络零售支付清算体网联在中国。可以说现在我国经济的高速发展,离不开CNAPS2。

银行信息系统应用架构详解 2511

PostgreSQL数据库WAL——XLogInsertRecord将日志记录写入WAL日志缓存

如图所示,一个PostgreSQl进程在组装wal数据之后,会在local内存中形成一个wal的数据链表。这个进程希望将链表中的数据拷贝到wal的buffer中。首先进程需要获取wal插入锁槽,然后根据当前已经写的wal位置和希望插入的wal记录的长度,在wal buffer中预置其wal位置,最后将local内存的wal数据链表中的数据拷贝到预置的wal页buffer中。在整个写入过程中,插入锁槽是一直持有的,在图中我们可以看到一共有8个插入锁槽,也就是说PostgreSQL目前只支持8个并发进程同时修.

肥叔菌的博客 1904

广东省道路工程检测练习试题(判断题)真题

按下式计算小于某粒径颗粒质量百分数:X=(A/B)x100( )49.、挖坑灌砂法适用于在现场测定基层(或底基层)、砂石路面及路基土的各种材料压实层的密度和压实度,但不适用于填石路堤等有大孔洞或大孔隙材料的压实度检测。95.挖坑灌砂法适用于在现场测定基层(或底基层)、砂石路面及路基土的各种材料压实层的密度和压实度,但不适用于填石路堤等有大孔洞或大孔隙材料的压实度检测( )107.以干密度 pd 为纵坐标,含水率w为横坐标,绘 pd-w 关系曲线,曲线上峰值点的纵、横坐标分别为最大干密度和最佳含水率( )

ZShy001238的博客 684

Ultralytics 框架中 model.predict() 返回的 results 对象的详细解析

通过掌握 results 对象的使用方法,您可以快速实现模型部署、数据分析与可视化。

浩瀚之水的专栏 748

PostgreSQL中wal日志具备幂等性吗?

数据库日志与幂等性 最近在看《The Internals of PostgreSQL》这本书时发现这样一段话: In short, the redo (replay) operation of non-backup block is not idempotent. Therefore, to preserve the correct replaying order, non-backup block records should replay if and only if its LSN is greate

Focus on PostgreSQL 1977

SDA 还是 SDI:SAP HANA 数据虚拟化与数据集成的取舍、组合与实战

结论先放在前面:SDA 面向数据虚拟化与联邦查询,强调不落地、不复制、按需实时访问;SDI 面向数据集成与复制,强调抽取、转换、装载与近实时增量同步。两者共享 Remote Source 与 Adapter 的理念,但侧重点与运行时组件明显不同。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 585

PostgreSQL查看wal日志大小

介绍了两种方法来获取wal日志的大小。

荷塘月色 1065

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Postgresql关于wal日志总结,一文搞清楚它的所有概念和相关操作

官方文档 https://www.postgresql.org/docs/11/wal-intro.html https://www.postgresql.org/docs/11/wal-configuration.html https://www.postgresql.org/docs/11/runtime-config-wal.html https://www.postgresql.org/docs/11/runtime-config-preset.html https://www.postgresql

lusklusklusk的博客 1万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

PostgreSQL WAL日志膨胀处理

PostgreSQL由于WAL日志的机制,导致其在不正确配置的情况下会出现磁盘空间暴涨的情况,本文档就此情景写一般处理办法。

weixin_42329915的博客 1421

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

上一篇: 数据开发流程图
下一篇: 如何实现MySQL对某一张表的binlog日志进行记录
CarsonBigData
博客等级 码龄9年 8316粉丝 166原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值