Re: Is drop/restore trigger transactional?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Aug 7, 2012 at 4:39 PM, Craig James <cjames@xxxxxxxxxxxxxx> wrote:
> On Tue, Aug 7, 2012 at 1:45 PM, Jeff Janes <jeff.janes@xxxxxxxxx> wrote:
>> On Tue, Aug 7, 2012 at 1:15 PM, Merlin Moncure <mmoncure@xxxxxxxxx> wrote:
>>> On Tue, Aug 7, 2012 at 1:48 PM, Craig James <cjames@xxxxxxxxxxxxxx> wrote:
>>>> I found this discussion from 2005 that says you can drop and restore a
>>>> trigger inside a transaction, but that doing so locks the whole table:
>>>>
>>>> http://archives.postgresql.org/pgsql-general/2005-01/msg01347.php
>>>>> From: Jeff Davis
>>>>>
>>>>> It got me curious enough that I tested it, and apparently droping a
>>>>> trigger locks the table. Any actions on that table must wait until the
>>>>> transaction that drops the trigger finishes.
>>>>>
>>>>> So, technically my system works, but requires a rather nasty lock while
>>>>> the transaction (the one that doesn't want the trigger to execute)
>>>>> finishes.
>>>>
>>>> I have a process that copies customer data from one database to
>>>> another, and we know that the trigger has already done its work.  The
>>>> trigger is thus redundant, but it slows the copy WAY down, so I wanted
>>>> to drop/restore it inside a transaction.
>>>>
>>>> Is it still true that drop-trigger inside a transaction will lock the
>>>> whole table?  We're using 8.4.
>>>
>>> absolutely -- the database needs to guard against other writers to the
>>> table doing inserts in the meantime.
>>
>> But why must it?  Why can't other writers simply obey the trigger,
>> since its removal has not yet been committed?
>>> there's no concept in SQL of
>>> 'enforce this trigger for all writers, except for me' nor should there
>>> be.
>>
>> Why shouldn't there be, other than the bother of implementing and
>> documenting it?  Sometimes theory needs to compromise with reality.
>> When we don't provide slightly dangerous ways to make those
>> compromises, people are forced to use very dangerous ways instead.
>>
>>>
>>> one possible workaround is to hack your trigger function so that it
>>> doesn't operate for particular roles.  so your trigger might be:
>>>
>>> IF current_user = 'bulk_writer' THEN
>>>   return new;
>>> END IF;
>>> <expensive stuff>
>>
>> I don't know Craig's case, but often the most expensive of the
>> "expensive stuff" is the bare fact of firing a trigger in the first
>> place.
>
> My use case is pretty simple: Copy some already-validated user data
> from one schema to another.  Since the trigger has already been
> applied, we're guaranteed that the data is already in the form we
> want.
>
> For your amusement: The trigger ensures that you can't buy illegal
> drugs, explosives, weapons of war, corrosives and other dangerous or
> illegal chemical compounds.  It executes a query against known
> compounds from the DEA, Homeland Security, Department of
> Transportation and several other lists.  Then calls a series of
> functions that implement "rules" to find illegal or dangerous
> compounds that aren't on anyone's list.  Some examples: "cocaine
> derivatives" for obvious reasons; "two or more nitro groups on a small
> molecule" to find chemicals that might explode; and "Metal-hydrogen
> bond" to find things that will catch fire if exposed to air.
>
> This is implemented in the database to esure that no matter how badly
> a programmer screws up an app, you still can't get these chemical
> compounds into an order.  The chemicals need to be in our database for
> informational purposes, but we don't want law enforcement knocking on
> our door.
>
> Obviously this is a very expensive trigger, but one that we can drop
> in a very specific circumstance.  But we NEVER want to drop it for
> everyone.  It seems like a very reasonable use-case to me.

well, there you go:  create a role that is excepted from having to run
through those checks and take appropriate precautions (password,
pg_hba.conf etc) so that only people/things that are supposed to
bypass the checks can do so.  then the trigger can look for the role
and punt.

merlin

-- 
Sent via pgsql-performance mailing list (pgsql-performance@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-performance


[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux