You're using mysql 5.1, This means the only engines you'll have available are MyISAM or innodb. in both cases adding a new column, regardless of nullability will require a complete, blocking, table rebuild during alter table.
You maybe be able to use the pt-online-schema change tool that does some tricks to rebuild the table in a less blocking manner but may not work out if you have complicated composite primary keys.
If you have a more recent version (5.6.22 Percona Build) you could use a tokudb storage engine that allows you to to "instantly" add columns. The way it's indexing works it propagates changes down as they're accessed.
While it appears that DMS supports migrating the SERIAL datatype, DMS doesn't support migrating default values like your SET DEFAULT nextval('pageviews_id_seq')
If you are running ongoing replication, then all the data in the read replica target is created in the source database, that is where the nextval from that sequence will be applied.
It kind of makes sense, because DMS is trying to explicity insert a value into that id
column, and you shouldn't explicitly set a column that is supposed to have its value generated by a sequence.
If you're using DMS to migrate a database with the intention to switch off the old one then you'll have to
- switch off DMS, then on the new database:
- create the sequence object
pageviews_id_seq
, setting the sequence to start at a value higher than the max id in the table, so it's nextval doesn't collide with an existing id
- alter the column to apply the
SET DEFAULT nextval('pageviews_id_seq')
In your specific case, there is a trigger on the source database (see link below to docs) which looks like this
CREATE OR REPLACE FUNCTION <objects_schema>.awsdms_intercept_ddl()
RETURNS event_trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
declare _qry text;
BEGIN
if (tg_tag='CREATE TABLE' or tg_tag='ALTER TABLE' or tg_tag='DROP TABLE') then
SELECT current_query() into _qry;
insert into <objects_schema>.awsdms_ddl_audit
values
(
default,current_timestamp,current_user,cast(TXID_CURRENT()as varchar(16)),tg_tag,0,'',current_schema,_qry
);
delete from <objects_schema>.awsdms_ddl_audit;
end if;
END;
$$;
It is trying to insert the default value for the first column in the table awsdms_ddl_audit
.
According to the docs the table should look like this
create table <objects_schema>.awsdms_ddl_audit
(
c_key bigserial primary key,
c_time timestamp, -- Informational
c_user varchar(64), -- Informational: current_user
c_txn varchar(16), -- Informational: current transaction
c_tag varchar(24), -- Either 'CREATE TABLE' or 'ALTER TABLE' or 'DROP TABLE'
c_oid integer, -- For future use - TG_OBJECTID
c_name varchar(64), -- For future use - TG_OBJECTNAME
c_schema varchar(64), -- For future use - TG_SCHEMANAME. For now - holds current_schema
c_ddlqry text -- The DDL query associated with the current DDL event
)
ckey
is supposed to be a bigserial
, so this should be inserting an incremented bigint automatically for you ( similar to IDENTITY
on MSSQL ). The error says that it is failing when trying to insert a NULL, so can you check the datatype for that c_key
column, I suspect in your DB the datatype isn't right.
!! Note that in the docs it says you need to do these thing in order
1. create the aws_ddl_audit
table
2. create the trigger function
3. attatch the trigger to the ddl_command_end then execute it
The trigger monitors all create
, update
and drop
table statements, which would include creating the aws_ddl_audit
table if you create the table after the trigger.
https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.PostgreSQL.html#CHAP_Source.PostgreSQL.Limitations
Best Answer
You seem to assume variable substitution for an SQL utility command like
ALTER TABLE
, but that's not implemented.Also not possible to pass values for utility commands to
EXECUTE
with theUSING
clause in plpgsql.Detailed explanation for both in this related answer on SO:
Concatenate the statement, then execute it - like @Abelisto hinted. But you don't need a variable, you can concatenate the lookup value directly:
The
SELECT
must return a single value.I cast to
text
explicitly, which is not strictly necessary. Casting the string literal to the target typeuuid
isn't required, either. Postgres will derive that from the column type automatically.Related: